在 linq 中合并列表

本文关键字:列表 合并 linq | 更新日期: 2023-09-27 18:18:01

在 linq 中,是否可以组合许多列表(相同类型(,以便两个列表,

列表 1 = {a,b,c} 和列表 2 = {x,y,z}

变成 {[1,a

] , [1,b] , [1,c] , [2,x] , [2,y] , [2,z] }

其中 [] 表示包含"列表标识符"的一对

问题在于拥有任意一副牌,其中每副牌都是列表集合中的一个列表。

正在尝试创建一个查询,以便我只能选择特定套牌中的牌,或类似于 2 副或更多套牌的牌。

这可能是一个重复的问题,但我不知道如何进一步搜索这个问题。

在 linq 中合并列表

List<List<int>> lists;
var combined = lists.Select((l, idx) => new { List = l, Idx = idx })
    .SelectMany(p => p.List.Select(i => Tuple.Create(p.Idx + 1, i)));
var list1 = new List<string>() {a,b,c};
var list2 = new List<string>() {x,y,z};
var combined = list1.Select(x => new { id = 1, v = x }).Concat(list2.Select(x => new { id = 2, v = x }));

通常我会建议使用Enumerable.Zip来组合多个列表,但是您似乎实际上希望将多个列表与列表计数器连接起来。

public IEnumerable<Tuple<int,T>> Combine<T>(params IEnumerable<T>[] lists) {
  return lists.Select((x,i) => x.Select(y => Tuple.Create(i+1,y))).SelectMany (l =>l);
}

更新完全错过了 SelectMany 具有索引选项,因此上面的代码可以编写为

public IEnumerable<Tuple<int,T>> Combine<T>(params IEnumerable<T>[] lists) {
  return lists.SelectMany((x,i) => x.Select(y => Tuple.Create(i+1,y)));
}

然后你可以做

 var list1 = new List<string> { "a", "b", "c" };
 var list2 = new List<string> { "x", "y", "z" };
 var combined = Combine(list1,list2);

组合将是元组的枚举,Item1是列表索引标识符(从 1 开始(,Item2是值。

此方法将处理多个列表,因此您可以使用以下命令轻松调用它:

var list3 = new List<string> { "f", "g" };
var combined =  Combine(list1,list2,list3);

您可以合并列表,如下所示:

var first = new List<string> {"a","b","c"};
var second = new List<string> {"x","y","z"};
var merged = first.Select(item => new { ListIndex = 1, Value = item}).ToList();
merged.AddRange(second.Select(item => new { ListIndex = 2, Value = item});
//or use concat
var merged = first.Select(item => new { ListIndex = 1, Value = item});
    .Concat(second.Select(item => new { ListIndex = 2, Value = item});

或者,如果您有以下来源

List<List<string>> lists = new List<List<string>>
                           {
                              new List<string> {"a","b","c"},
                              new List<string> {"x","y","z"}
                           };

你可以做:

var merged = lists.SelectMany((item, index) => 
                         item.Select(s => new { ListIndex = index, Value = s}));

请注意,这将生成一个从 0 开始的列表,所以如果你真的需要一个 1 个碱基的列表,只需执行 ListIndex = index +1

另外,如果您经常使用它,我会将其创建为一个特定的实体,例如

struct ListIdentValue
{
   public int ListIndex {get; private set;}
   public string Value {get; private set;}
   public ListIdentValue(int listIndex, string value) {...}
}

尝试使用 Concat

new[] {'a','b','c'}
.Select(v=>new Tuple<int,char>(1, v))
.Concat(
    new[] {'x','y','z'}.Select(v=>new Tuple<int,char>(2, v))
)
    string[] a = { "a", "b", "c" };
    string[] b = { "x", "z", "y" };

    var t =
    (
    from ai in a
    select new { listNo = 1, Item = ai }
    ).Union
    (
    from bi in b
    select new { listNo = 2, Item = bi }
        );

var t =
        (
        from ai in a
        select new object[] { 1, ai }
        ).Union
        (
        from bi in b
        select new object[] { 2, bi }
            );