在linq中,是否可以组合多个列表(相同类型),例如两个列表,
列表1 = {a,b,c}和列表2 = {x,y,z}
变成{[1,a],[1,b],[1,c],[2,x],[2,y],[2,z]}
其中[]表示包含“列表标识符”的对
问题在于拥有任意牌组,其中每个牌组都是列表集合中的列表。
我正在尝试创建一个查询,以便我只能选择特定卡片中的卡片,或类似于2张或更多卡片的卡片。
这可能是一个重复的问题,但我不知道如何进一步搜索这个问题。
答案 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 }
);