【问题标题】:Get certain item from each Tuple from List从列表中的每个元组中获取特定项目
【发布时间】:2012-12-30 01:02:14
【问题描述】:

TuplesList 中创建一个列表(例如,每个Tuple 的第一项)的正确方法是什么?

如果我有一个List<Tuple<string,string>>,我如何获得每个Tuple 中第一个字符串的List<string>

【问题讨论】:

    标签: c# string list tuples


    【解决方案1】:
    List<string> list = tuples.Select(t => t.Item1).ToList();
    

    或者,内存成本可能更低:

    List<string> list = new List<String>(tuples.Count);
    list.AddRange(tuples.Select(t => t.Item1));
    

    因为它避免了List.AddToList中的加倍算法。

    【讨论】:

    • 在大多数情况下,我会认为第二个建议是微优化并避免它 - 它只会给代码增加噪音。
    • @DanielBrückner:是的,提到它只是因为人们有时对ToListToArray 过于慷慨。当序列很大时,您可以使用第二种方法避免OutOfMemoryExceptions。它可以保护高达 50% 的内存。我永远不会忘记它:stackoverflow.com/questions/10519275/…
    • 更简洁的方法是将 IEnumerable 传递给列表构造函数。 List 将自己调整到所需的容量,这变成了一个单行。
    • @KeithS:不,只有当IEnumerable 可以转换为ICollection 时才有效,上述情况并非如此。因此ToList 使用List.Add(有或没有构造函数)枚举整个序列。
    • 查看 TypeDescriptor 可以为您提供支持。我的错误(或者更确切地说,是 MSDN 的错误,因为它确实断言列表的大小会适当)。
    【解决方案2】:

    一点 Linq 就可以解决问题:

    var myStringList = myTupleList.Select(t=>t.Item1).ToList();
    

    作为解释,由于 Tim 发布了几乎相同的答案,因此 Select() 创建了一个 1:1 的“投影”;它接受 Enumerable 的每个输入元素,并为每个输入元素计算 lambda 表达式并将结果作为具有相同数量元素的新 Enumerable 的元素返回。然后 ToList() 将遍历 Select() 生成的 Enumerable,并将每个元素一次添加到一个新的 List&lt;T&gt; 实例中。

    Tim 对内存效率有很好的看法; ToList() 将创建一个列表并一次添加一个元素,这将导致 List 不断调整其底层数组的大小,每次将其加倍以确保其具有适当的容量。对于一个大列表,这可能会导致 OutOfMemoryExceptions,并且它将导致 CLR 为列表分配比必要更多的内存,除非元素的数量恰好是 2 的幂。

    【讨论】:

      【解决方案3】:

      如果您有List&lt;Tuple&lt;string, string&gt;&gt; listoftuples,您可以使用 List 的 Select 方法实现从每个 Tuple 中获取第一个字符串。

      看起来像这样:

      List<string> firstelements = listoftuples.Select(t => t.Item1).ToList();
      

      【讨论】:

      • 不是List&lt;T&gt;的方法;它是 System.Linq 库的一部分。
      • 对,但是 List 有一个实现。我已经澄清了我的答案。
      • SelectEnumerable&lt;T&gt; 中定义的扩展方法,适用于所有实现IEnumerable&lt;T&gt; - List&lt;T&gt; 在这种情况下没什么特别的。
      • @Jim - 它没有。检查 MSDN 文档。它是一种扩展方法,可以应用于 List,因为 List 是 IList,它是 IEnumerables。但是,它是由静态 System.Linq.Enumerable 类定义的。 msdn.microsoft.com/en-us/library/system.linq.enumerable.aspx
      • 有趣。不知道那个。我的观点是可以使用 Select 方法 - 因为其他答案(更好地)涵盖了这一点,我可能会删除我的。
      【解决方案4】:

      通用变体: 用于选择集合元组长度未知的特定项目,即 2,3,4 ...:

          static IEnumerable TupleListSelectQuery<T>(IEnumerable<T> lst, int index) where T : IStructuralEquatable, IStructuralComparable, IComparable
          {
              return lst.Select(t => typeof(T).GetProperty("Item" + Convert.ToString(itemNumber)).GetValue(t)).ToList();
          }
      

      index 的值对应于元组的枚举方式,即 1,2,3 ...(不是 0,1,2...)。

      【讨论】:

        猜你喜欢
        • 2013-07-22
        • 1970-01-01
        • 1970-01-01
        • 2011-11-22
        • 1970-01-01
        • 2022-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多