Sono possibili elenchi bidimensionali in c #?


91

Vorrei creare un elenco multidimensionale. Per riferimento, sto lavorando a un analizzatore di playlist.

Ho un file / elenco di file, che il mio programma salva in un elenco standard. Una riga del file in ogni voce dell'elenco.

Quindi analizzo l'elenco con espressioni regolari per trovare righe specifiche. Alcuni dei dati / risultati delle righe devono essere inseriti in un nuovo elenco multidimensionale ; poiché non so quanti risultati / dati mi ritroverò, non posso usare un array multidimensionale.

Ecco i dati che voglio inserire:

Elenco
(
    [0] => Elenco
        (
            [0] => Track ID
            [1] => Nome
            [2] => Artista
            [3] => Album
            [4] => Conteggio riproduzioni
            [5] => Salta conteggio

        )
    [1] => Elenco
        (
E così via....

Esempio reale:

Elenco
(
    [0] => Elenco
        (
            [0] => 2349
            [1] => Il momento migliore della tua vita
            [2] => Daft Punk
            [3] => Umano dopo tutto
            [4] => 3
            [5] => 2

        )
    [1] => Elenco
        (

Quindi sì, mlist [0] [0] otterrebbe TrackID dalla canzone 1, mlist [1] [0] dalla canzone 2 ecc.

Ma sto avendo enormi problemi nella creazione di un elenco multidimensionale. Finora ho pensato

List<List<string>> matrix = new List<List<string>>();

Ma non ho davvero fatto molti più progressi :(

Risposte:


140

Beh sicuramente possibile utilizzare una List<List<string>>dove ti piacerebbe quindi scrivere:

List<string> track = new List<string>();
track.Add("2349");
track.Add("The Prime Time of Your Life");
// etc
matrix.Add(track);

Ma perché dovresti farlo invece di costruire la tua classe per rappresentare una traccia, con le proprietà Track ID, Name, Artist, Album, Play Count e Skip Count? Quindi basta avere un file List<Track>.


1
Hmm, onestamente non sono sicuro di come farlo! Ho cercato di creare una classe per la gestione della playlist da sola, ma immagino che sia un'idea migliore.
CasperT

Inoltre, non sarebbe necessario sapere quante tracce creerò / memorizzerò alla fine?
CasperT

2
No, perché List <Track> è ancora dimensionato dinamicamente. Dovresti analizzare i dati per una traccia, creare una nuova istanza di Track, aggiungerla a List <Track> e quindi analizzare quella successiva, ecc.
Jon Skeet,

caspert, List <T> tiene traccia della quantità di oggetti che memorizza per te. Puoi accedere all'importo chiamando List <T> .Count
Spoike

3
@CasperT Per favore, fai quello che molti hanno suggerito e fai una Tracklezione. Sarà molto più facile capire / mantenere il codice. Se rappresenti una traccia come un elenco di stringhe, gli indici in cui memorizzi un particolare attributo dovranno essere sincronizzati in tutte le istanze in cui provi ad accedere alle informazioni sulla traccia. Diventerà noioso da implementare ogni volta e impossibile eseguire il debug. Per favore, per il tuo bene, guarda nelle classi. :)
Alexander Kondratskiy

103

Come ha detto Jon Skeet , puoi farlo con un file List<Track>. La classe Track sarebbe simile a questa:

public class Track {
    public int TrackID { get; set; }
    public string Name { get; set; }
    public string Artist { get; set; }
    public string Album { get; set; }
    public int PlayCount { get; set; }
    public int SkipCount { get; set; }
}

E per creare un elenco di tracce come un List<Track>fai semplicemente questo:

var trackList = new List<Track>();

L'aggiunta di tracce può essere semplice come questa:

trackList.add( new Track {
    TrackID = 1234,
    Name = "I'm Gonna Be (500 Miles)",
    Artist = "The Proclaimers",
    Album = "Finest",
    PlayCount = 10,
    SkipCount = 1
});

L'accesso alle tracce può essere effettuato con l'operatore di indicizzazione:

Track firstTrack = trackList[0];

Spero che sia di aiuto.


4
Se vuoi essere davvero esperto, Track potrebbe anche essere una struttura. ;)
Spoike

3
Non con la definizione che hai dato ... Le strutture dovrebbero avere una dimensione dell'istanza inferiore a 16 byte ...
Ian

@Ian: Hmm. Non ne ero consapevole. Controlla rapidamente il documento MSDN per questo e risulta che le strutture devono essere inferiori a 16 byte. Grazie per segnalarlo.
Spoike

14
Non è necessario che lo siano, è solo una raccomandazione. Non importa poi così tanto; scegli struct se hai bisogno della semantica dei valori altrimenti solo della classe. Se non lo sai, usa un corso.
jason

35

Questo è il modo più semplice che ho trovato per farlo.

List<List<String>> matrix= new List<List<String>>(); //Creates new nested List
matrix.Add(new List<String>()); //Adds new sub List
matrix[0].Add("2349"); //Add values to the sub List at index 0
matrix[0].Add("The Prime of Your Life");
matrix[0].Add("Daft Punk");
matrix[0].Add("Human After All");
matrix[0].Add("3");
matrix[0].Add("2");

Recuperare i valori è ancora più semplice

string title = matrix[0][1]; //Retrieve value at index 1 from sub List at index 0

12

un altro lavoro attorno al quale ho usato è stato ...

List<int []> itemIDs = new List<int[]>();

itemIDs.Add( new int[2] { 101, 202 } );

La libreria su cui sto lavorando ha una struttura di classi molto formale e non volevo materiale extra in modo efficace per il privilegio di registrare due int "correlati".

Si basa sul programmatore che inserisce solo un array di 2 elementi ma poiché non è un elemento comune penso che funzioni.


2

Puoi anche ... fare in questo modo,

List<List<Object>> Parent=new  List<List<Object>>();

List<Object> Child=new List<Object>();
child.Add(2349);
child.Add("Daft Punk");
child.Add("Human");
.
.
Parent.Add(child);

se hai bisogno di un altro elemento (figlio), crea una nuova istanza di figlio,

Child=new List<Object>();
child.Add(2323);
child.Add("asds");
child.Add("jshds");
.
.
Parent.Add(child);

2

Ecco come creare un elenco bidimensionale

        // Generating lists in a loop.
        List<List<string>> biglist = new List<List<string>>();

        for(int i = 1; i <= 10; i++)
        {
            List<string> list1 = new List<string>();
            biglist.Add(list1);
        }

        // Populating the lists
        for (int i = 0; i < 10; i++)
        {
            for(int j = 0; j < 10; j++)
            {
                biglist[i].Add((i).ToString() + " " + j.ToString());
            }
        }

        textbox1.Text = biglist[5][9] + "\n";

Essere consapevoli del pericolo di accedere a una posizione che non è popolata.


1

Ero solito:

List<List<String>> List1 = new List<List<String>>
var List<int> = new List<int>();
List.add("Test");
List.add("Test2");
List1.add(List);
var List<int> = new List<int>();
List.add("Test3");
List1.add(List);

che è uguale a:

List1
(
[0] => List2 // List1[0][x]
    (
        [0] => Test  // List[0][0] etc.
        [1] => Test2

    )
[1] => List2
    (
        [0] => Test3

0

Puoi anche utilizzare DataTable: puoi definire il numero di colonne e il loro tipo e quindi aggiungere righe http://www.dotnetperls.com/datatable


È meglio attenersi List<Track>all'approccio e utilizzare a BindingSource, semplicemente aggiungendo un DataSource al proprio DataGridViewtipo Trackper supportare classi fortemente tipizzate nel codice e una visualizzazione facile da configurare delle tracce all'interno della visualizzazione della griglia dei dati.
Oliver

D'accordo, ma a volte non vuoi visualizzare i dati istantaneamente e non vuoi creare un'altra classe solo per usarla in un solo posto, quindi preferisco usare una soluzione esistente. ... Volevo solo indicare un altro modo per risolvere questo problema! ;)
Val

0

Ecco qualcosa che ho creato tempo fa per un motore di gioco su cui stavo lavorando. È stato utilizzato come contenitore di variabili oggetto locali. Fondamentalmente, lo usi come un normale elenco, ma mantiene il valore alla posizione di qualunque sia il nome della stringa (o ID). Un po 'di modifica e avrai il tuo elenco 2D.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GameEngineInterpreter
{
    public class VariableList<T>
    {
        private List<string> list1;
        private List<T> list2;

        /// <summary>
        /// Initialize a new Variable List
        /// </summary>
        public VariableList()
        {
            list1 = new List<string>();
            list2 = new List<T>();
        }

        /// <summary>
        /// Set the value of a variable. If the variable does not exist, then it is created
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        /// <param name="value">The value of the variable</param>
        public void Set(string variable, T value)
        {
            if (!list1.Contains(variable))
            {
                list1.Add(variable);
                list2.Add(value);
            }
            else
            {
                list2[list1.IndexOf(variable)] = value;
            }
        }

        /// <summary>
        /// Remove the variable if it exists
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        public void Remove(string variable)
        {
            if (list1.Contains(variable))
            {
                list2.RemoveAt(list1.IndexOf(variable));
                list1.RemoveAt(list1.IndexOf(variable));
            }
        }

        /// <summary>
        /// Clears the variable list
        /// </summary>
        public void Clear()
        {
            list1.Clear();
            list2.Clear();
        }

        /// <summary>
        /// Get the value of the variable if it exists
        /// </summary>
        /// <param name="variable">Name or ID of the variable</param>
        /// <returns>Value</returns>
        public T Get(string variable)
        {
            if (list1.Contains(variable))
            {
                return (list2[list1.IndexOf(variable)]);
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// Get a string list of all the variables 
        /// </summary>
        /// <returns>List string</string></returns>
        public List<string> GetList()
        {
            return (list1);
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.