2

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

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

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

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

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

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

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

4

6 回答 6

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)));
于 2013-06-11T08:45:36.947 回答
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 }));
于 2013-06-11T08:46:07.787 回答
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);
}

UPDATE 完全错过了 SelectMany 有 index 选项,所以上面的代码可以写成

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);
于 2013-06-11T08:57:34.210 回答
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))
)
于 2013-06-11T08:50:42.490 回答
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 开始的列表,只需执行ListIndex = index +1.

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

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

   public ListIdentValue(int listIndex, string value) {...}
}
于 2013-06-11T09:09:07.183 回答
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 }
            );
于 2013-06-11T08:47:58.000 回答