2009-03-20 20 views
73

Me gustaría configurar una lista multidimensional. Como referencia, estoy trabajando en un analizador de lista de reproducción.¿Son posibles las Listas bidimensionales en C#?

Tengo un archivo/lista de archivos, que mi programa guarda en una lista estándar. Una línea del archivo en cada entrada de la lista.

Luego analizo la lista con expresiones regulares para encontrar líneas específicas. Algunos de los datos/resultados de las líneas deben colocarse en una nueva lista multidimensional; ya que no sé con cuántos resultados/datos terminaré, no puedo usar una matriz multidimensional.

Estos son los datos que quiero insertar:

 
List 
(
    [0] => List 
     (
      [0] => Track ID 
      [1] => Name 
      [2] => Artist 
      [3] => Album 
      [4] => Play Count 
      [5] => Skip Count 

     ) 
    [1] => List 
     (
And so on.... 

real Ejemplo:

 
List 
(
    [0] => List 
     (
      [0] => 2349 
      [1] => The Prime Time of Your Life 
      [2] => Daft Punk 
      [3] => Human After All 
      [4] => 3 
      [5] => 2 

     ) 
    [1] => List 
     (

Así que sí, mlist [0] [0] obtendría TrackID de la canción 1, mlist [1 ] [0] de la canción 2, etc.

Pero estoy teniendo grandes problemas al crear una lista multidimensional. Hasta aquí he llegado con

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

Pero realmente no han tenido mucho más progreso :(

Respuesta

113

Bueno que sin duda puede utilizar un List<List<string>> el lugar donde quiere escribir a continuación:

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

¿Pero por qué harías eso en lugar de construir tu propia clase para representar una pista, con las propiedades Track ID, Name, Artist, Album, Play Count y Skip Count? Entonces simplemente ten un List<Track> .

+1

Hmm, honestamente, no estoy seguro de cómo hacerlo. Miré cómo configurar una clase para el manejo de la lista de reproducción solo, pero supongo que es una mejor idea. – CasperT

+0

Además, ¿no sería necesario saber cuántas pistas crearé/almacenaré? – CasperT

+2

No, porque la lista todavía tiene un tamaño dinámico. Puede analizar los datos de una pista, crear una nueva instancia de Pista, agregarla a la lista y luego analizar la siguiente, etc. –

89

Como Jon Skeet mencionó que puede hacerlo con un List<Track> en su lugar. La clase de pista sería algo como esto:

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; } 
} 

Y para crear una lista de pistas como List<Track> sólo tiene que hacer esto:

var trackList = new List<Track>(); 

pistas Adición puede ser tan simple como esto:

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

Acceso a las pistas se puede hacer con el operador de indización:

Track firstTrack = trackList[0]; 

Espero que esto ayude.

+4

Si quieres ser realmente inteligente, Track también podría ser una estructura. ;) – Spoike

+3

No con la definición que has dado ... Las estructuras deberían tener un tamaño de instancia de menos de 16 bytes ... – Ian

+1

¡Gracias por la demostración! – CasperT

11

otra obra en torno al cual he utilizado era ...

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

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

La biblioteca que estoy trabajando tiene una estructura de clases muy formal y no wa no hay material extra en forma eficaz para la privilegio de grabar dos ints 'relacionados'.

Se basa en que el programador ingrese solo una matriz de 2 elementos, pero como no es un elemento común, creo que funciona.

1

utilicé:

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); 

que es igual a:

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

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

Esto es útil para mi! ¡Gracias! –

0

También puede utilizar DataTable - se puede definir entonces el número de columnas y sus tipos y luego añadir filas http://www.dotnetperls.com/datatable

+0

Mejor apegue al enfoque 'List ' y use un 'BindingSource', simplemente agregando un DataSource a su' DataGridView' del tipo 'Track' para soportar clases fuertemente tipadas en el código y fácil de configurar de las pistas dentro del código vista de cuadrícula de datos. – Oliver

+0

De acuerdo, pero a veces no desea mostrar los datos de forma instantánea y no desea crear una clase más solo para usarla en un solo lugar, por lo que prefiero usar una solución existente. ... ¡Solo quería señalar una forma más de resolver esto! ;) – Val

28

Esta es la forma más fácil que he encontrado para hacerlo.

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"); 

Para recuperar valores es aún más fácil

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

Aunque la sugerencia anterior sobre una clase Track era la mejor para los requisitos del OP, ESTA solución es la mejor para mí para construir una cuadrícula de objetos bidimensional. ¡Gracias! – CigarDoug

+1

Sí, esto es lo que he encontrado que es la solución más simple y elegante, ¡me alegro de haber ayudado! –

+1

¡Simple y útil! ¡Gracias! –

0

Aquí es cómo hacer una lista de 2 dimensiones

// La generación de listas en un bucle. List> biglist = new List>();

 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"; 

Tenga en cuenta el peligro de acceder a una ubicación que no está ocupada.

2

Puede also..do de esta manera,

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); 

si necesita otro elemento (hijo), crear una nueva instancia del niño,

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

Aquí hay un poco de algo que Hice hace un tiempo para un motor de juego en el que estaba trabajando. Se usó como un titular de variable de objeto local. Básicamente, lo usa como una lista normal, pero mantiene el valor en la posición de cualquier nombre de cadena (o ID). Un poco de modificación, y tendrás tu lista 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); 
     } 
    } 
} 
Cuestiones relacionadas