使用 LINQ 交错两个列表

Using LINQ To Interleave Two Lists

所以这就是我正在尝试做的事情:

symbolList: 1,1,1,2,2,2
valueList:  a1,b1,c1,a2,b2,c2
result:     1|a1|b1|c1,2|a2|b2|c2

每个符号的a,b,c都是不同的值 对于每个符号,将有相同数量的对应值。所以对于符号 1,我想加入三个值。对于符号 2,我希望将第二组三个值连接到它,等等。 但是,根据我目前的实施,我目前得到:

result:     1|a1|b1|c1|a2|b2|c2, 2|a1|b1|c1|a2|b2|c2

这是我当前的代码:

List<string> results = symbolList.Distinct().Select(f => 
String.Join("|", new List<string>() { f }.Concat(valueList))).ToList();

string value = string.Join(",", results);

我尝试过以某种方式使用 group by,但没有找到可行的结果。非常感谢任何帮助。

你能试试这个吗:

List<string> symbolList = new List<string>() { "1", "1", "1", "2", "2", "2" };
List<string> valueList = new List<string>() { "a", "b", "c", "a", "b", "c" };

string value =  string.Join(",", symbolList.Distinct().
                Select(f => String.Join("|", new List<string>() { f }
                .Concat(valueList.Distinct()))).ToList());

Console.WriteLine("result: " + value);

这段代码给了我 result: "1|a|b|c,2|a|b|c".

希望这就是你想要的。

根据您的描述,配对索引似乎很重要,您并没有尝试进行盲目交错。下面是如何使用 GroupBy 来实现的,我还在中间放了一个 3 来演示排序。

List<string> symbolList = new List<string>() { "1", "1", "3", "2", "2", "2" };
List<string> valueList = new List<string>() { "a1", "b1", "c3", "a2", "b2", "c2" };

var items = symbolList.Zip(valueList, (symbol, value) => new {symbol, value}) //pairs the like indexes with each other in to an anonymous type.
    .GroupBy(pair => pair.symbol, pair => pair.value) //Group together the values that share the same symbol
    .OrderBy(group => group.Key) //optional, only if you want the output to be 1,2,3
    .Select(group => String.Join("|", (new[] {group.Key}).Concat(group))); //Build up the "|" separated groups.
var result = String.Join(",", items); //Join together the groupings separated by ","

Console.WriteLine("result: " + result);

Click to Run

它给出了结果result: 1|a1|b1,2|a2|b2|c2,3|c3

虽然不是原问题的答案,但严格回答标题(这是我来这里寻找的,只是简单地交错两个列表):

var interleaved = list1.Zip(list2, (a, b) => new[] { a, b }).SelectMany(p => p);

示例:

var l1 = Enumerable.Range(0, 10).Select(i => (char) ('0' + i));
var l2 = Enumerable.Range(0, 10).Select(i => (char) ('A' + i));

var interleaved = l1.Zip(l2, (a, b) => new[] { a, b }).SelectMany(p => p);