二维列表在 c # 中可能吗?

我想建立一个多维列表。 作为参考,我正在开发一个播放列表分析器。

我有一个文件/文件列表,我的程序将它保存在一个标准列表中。每个列表条目中的文件中的一行。

然后使用正则表达式分析列表以找到特定的行。 这些行中的一些数据/结果需要放到一个新的 多维的列表中; 因为我不知道最终会得到多少结果/数据,所以不能使用多维数组。

下面是我要插入的数据:

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


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

真正的例子:

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
(

所以,mlist [0][0]会从歌曲1中获得 TrackID,从歌曲2中获得 mlist [1][0]等等。

但是我在创建一个多维列表时遇到了很大的问题。 到目前为止,我想到了

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

但是我并没有取得更多的进步:

337715 次浏览

Well you certainly can use a List<List<string>> where you'd then write:

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

But why would you do that instead of building your own class to represent a track, with Track ID, Name, Artist, Album, Play Count and Skip Count properties? Then just have a List<Track>.

As Jon Skeet mentioned you can do it with a List<Track> instead. The Track class would look something like this:

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

And to create a track list as a List<Track> you simply do this:

var trackList = new List<Track>();

Adding tracks can be as simple as this:

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

Accessing tracks can be done with the indexing operator:

Track firstTrack = trackList[0];

Hope this helps.

another work around which i have used was...

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


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

The library i'm working on has a very formal class structure and i didn't wan't extra stuff in there effectively for the privilege of recording two 'related' ints.

Relies on the programmer entering only a 2 item array but as it's not a common item i think it works.

I used:

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

that equals:

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


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

You can also use DataTable - you can define then the number of columns and their types and then add rows http://www.dotnetperls.com/datatable

This is the easiest way i have found to do it.

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

To retrieve values is even easier

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

Here is how to make a 2 dimensional list

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

Be aware of the danger of accessing a location that is not populated.

You can also..do in this way,

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

if you need another item(child), create a new instance of child,

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

Here's a little something that I made a while ago for a game engine I was working on. It was used as a local object variable holder. Basically, you use it as a normal list, but it holds the value at the position of what ever the string name is(or ID). A bit of modification, and you will have your 2D list.

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

Just because it hasnt been mentioned yet, sometimes I prefer a List<Dictionary<string, string>>. There are cases where I just dont want to make a custom object for whatever reason, and this super simple data structure is pretty flexible. I realize everything is a string which is innefficient, and it forces you to parse and stringify when incrementing the PlayCount, but it might be worth it to some people.

var trackList = new List<Dictionary<string, string>>();


var track = new Dictionary<string, string>();
track.Add("TrackID"  , "1234");
track.Add("Name"     , "I'm Gonna Be (500 Miles)");
track.Add("Artist"   , "The Proclaimers");
track.Add("Album"    , "Finest");
track.Add("PlayCount", "10");
track.Add("SkipCount", "1");
trackList.Add(track);

This actually has a couple benefits over a custom object, namely, you can add a new key value to some of the tracks, without needing to add it to all the tracks, and the existing code will still work without recompiling. Obviously you have to recompile if you write code to do something with those new keys, but its not required. Second, if you ever store the data in a file you probably want it to be human readable (i would) in which case its all strings anyway. You can add, remove, or modify keys or values with a text editor, and this data structure is able to handle it.

You can create 2D list in C# in this way,

List<List<int>> list = new List<List<int>>{
new List<int> { 1, 2, 3 },
new List<int> { 4, 5, 6 },
new List<int> { 9, 8, 9 }
};