结合linq中的列表

时间:2013-06-11 08:40:10

标签: c# linq

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

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

变成{[1,a],[1,b],[1,c],[2,x],[2,y],[2,z]}

其中[]表示包含“列表标识符”的对

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

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

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

6 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

通常我建议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);

答案 3 :(得分:1)

尝试使用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))
)

答案 4 :(得分:1)

您可以合并以下列表:

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-base列表,只需执行ListIndex = index +1

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

struct ListIdentValue
{
   public int ListIndex {get; private set;}
   public string Value {get; private set;}

   public ListIdentValue(int listIndex, string value) {...}
}

答案 5 :(得分:0)

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