【问题标题】:Are 2 dimensional Lists possible in c#?c# 中是否可以使用二维列表?
【发布时间】:2009-03-20 08:06:34
【问题描述】:

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

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

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

这是我要插入的数据:

列表 ( [0] => 列表 ( [0] => 曲目 ID [1] => 名称 [2] => 艺术家 [3] => 专辑 [4] => 播放次数 [5] => 跳过计数 ) [1] => 列表 ( 等等....

真实例子:

列表 ( [0] => 列表 ( [0] => 2349 [1] => 人生的黄金时期 [2] => 愚蠢的朋克 [3] => 毕竟是人类 [4] => 3 [5] => 2 ) [1] => 列表 (

是的,mlist[0][0] 将从歌曲 1 中获取 TrackID,mlist[1][0] 从歌曲 2 中获取等等。

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

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

但我并没有真正取得更多进展:(

【问题讨论】:

    标签: c# list


    【解决方案1】:

    嗯,你当然可以使用List&lt;List&lt;string&gt;&gt;,然后你会写:

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

    但是,您为什么要这样做而不是构建自己的类来表示曲目,并使用 Track ID、Name、Artist、Album、Play Count 和 Skip Count 属性?然后只需一个List&lt;Track&gt;

    【讨论】:

    • 嗯,我真的不知道该怎么做!我考虑单独设置一个播放列表处理类,但我想这是一个更好的主意。
    • 另外,不需要知道我最终会创建/存储多少首曲目吗?
    • 否,因为 List 仍然是动态调整大小的。您将解析一个轨道的数据,创建一个新的 Track 实例,将其添加到 List 然后解析下一个,等等。
    • caspert,List 会跟踪它为您存储的对象数量。您可以通过调用 List.Count 访问金额
    • @CasperT 请按照许多人的建议做一个Track 课程。理解/维护代码会容易得多。如果您将轨道表示为字符串列表,那么您存储特定属性的索引必须在您尝试访问轨道信息的所有实例之间同步。每次实现都会变得乏味且无法调试。为了您自己,请查看课程。 :)
    【解决方案2】:

    正如Jon Skeet 提到的,您可以使用List&lt;Track&gt; 来代替。 Track 类看起来像这样:

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

    要创建一个List&lt;Track&gt; 的曲目列表,您只需这样做:

    var trackList = new List<Track>();
    

    添加曲目可以这么简单:

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

    可以使用索引操作符访问轨道:

    Track firstTrack = trackList[0];
    

    希望这会有所帮助。

    【讨论】:

    • 如果你想真正精明,Track 也可以是一个结构体。 ;)
    • 不符合您给出的定义...结构的实例大小应小于 16 字节...
    • @Ian:嗯。我没有意识到这一点。快速检查了 MSDN 文档,结果发现结构需要小于 16 个字节。感谢您指出。
    • 他们没有需要,这只是一个建议。没那么重要。如果您需要值语义,请选择结构,否则只需类。如果您不知道,请使用课程。
    【解决方案3】:

    这是我发现的最简单的方法。

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

    检索值更容易

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

    【讨论】:

      【解决方案4】:

      我使用的另一项工作是......

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

      我正在研究的库有一个非常正式的类结构,我不想在其中有效地记录两个“相关”整数的特权。

      依赖于程序员只输入一个 2 项数组,但由于它不是一个常见的项,我认为它可以工作。

      【讨论】:

        【解决方案5】:

        你也可以..这样做,

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

        如果您需要另一个项目(孩子), 创建一个新的 child 实例,

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

        【讨论】:

          【解决方案6】:

          这里是如何制作一个二维列表

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

          请注意访问无人区的危险。

          【讨论】:

            【解决方案7】:

            我用过:

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

            等于:

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

            【讨论】:

              【解决方案8】:

              您也可以使用 DataTable - 您可以定义列数及其类型,然后添加行 http://www.dotnetperls.com/datatable

              【讨论】:

              • 最好坚持使用List&lt;Track&gt; 方法并使用BindingSource,只需向DataGridView 添加Track 类型的DataSource 即可支持代码中的强类型类且易于配置数据网格视图中轨道的可视化。
              • 同意,但有时您不想立即显示数据,也不想再创建一个类只是为了在一个地方使用它,所以我更喜欢使用现有的解决方案。 ...只是想指出另一种解决此问题的方法! ;)
              【解决方案9】:

              这是我不久前为我正在开发的游戏引擎制作的一些东西。它被用作局部对象变量持有者。基本上,您将它用作普通列表,但它将值保存在字符串名称(或 ID)的位置。稍作修改,您将获得 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);
                      }
                  }
              }
              

              【讨论】:

                【解决方案10】:

                只是因为它还没有被提及,所以有时我更喜欢 List>。在某些情况下,我只是出于某种原因不想制作自定义对象,而这种超级简单的数据结构非常灵活。我意识到一切都是一个效率低下的字符串,它会在增加 PlayCount 时强制您进行解析和字符串化,但对某些人来说可能是值得的。

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

                这实际上比自定义对象有几个好处,即您可以向某些轨道添加新的键值,而无需将其添加到所有轨道,并且现有代码无需重新编译仍可工作。显然,如果您编写代码以使用这些新密钥执行某些操作,则必须重新编译,但这不是必需的。其次,如果您曾经将数据存储在文件中,您可能希望它是人类可读的(我愿意),在这种情况下,无论如何它都是字符串。您可以使用文本编辑器添加、删除或修改键或值,此数据结构能够处理它。

                【讨论】:

                  【解决方案11】:

                  你可以用这种方式在C#中创建二维列表,

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

                  【讨论】:

                    猜你喜欢
                    • 2019-11-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-10-17
                    • 2012-12-11
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-03-10
                    • 1970-01-01
                    相关资源
                    最近更新 更多