[英]C# LINQ Zipping 2 list of lists based on uniqueness of objects
I am trying to zip 2 lists of lists of objects - only where the resulting zipped list would contain lists of distinct objects (list 2's lists sometimes have duplicate objects when compared to list 1).我正在尝试压缩 2 个对象列表列表 - 仅在生成的压缩列表将包含不同对象列表的地方(与列表 1 相比,列表 2 的列表有时具有重复的对象)。 The count of objects in the resultant list must be maintained, meaning we can't have lists of differing sizes.
结果列表中的对象计数必须保持不变,这意味着我们不能拥有不同大小的列表。 The number of lists in list 1 is greater the number in list 2. Which would mean repeatedly going through list 2 when zipping.
列表 1 中的列表数量大于列表 2 中的数量。这意味着在压缩时重复遍历列表 2。
The above is represented using loops below.以上使用下面的循环表示。 Is this possible using only linq?
这可以仅使用 linq 吗?
//this list of list contains the larger number of elements to which the 2nd list of list needs to be joined
List<List<object>> FullList = new List<List<object>>(); //is not empty - instantiated with some list
//2nd list of list - contains duplicates of the 1st list in terms of the objects in the underlying list
List<List<object>> comboBaseList = new List<List<object>>(); //is not empty - instantiated with some list
List<List<object>> comboList = comboBaseList;
//need to zip lists where there are no duplicate objects in the 2nd list's list, the count of the 1st list of list remains the same as FullList
List<List<object>> finalList = new List<List<object>>(); //empty - meant to hold final combined list
int i = 0;
foreach iList in FullList
{
if (i < comboList.count)
{
while (iList.Select(x => x.Id).Contains(comboList[i].Select(y => y.Id)))
{
i += 1;
}
finalList.Add(iList.Zip(comboList[i], (x, y) => x.Union(y))); //**CAN WE BYPASS THE LOOPS AND JUST USE LINQ?
comboList.RemoveAt(i);
i = 0;
}
else
{
comboList = comboBaseList;
i = 0;
}
}
To simplify the data I'll use lists of lists of integers - which could be the Id's of the objects in my case为了简化数据,我将使用整数列表的列表 - 在我的情况下这可能是对象的 Id
FullList =
(
{1,2,3},
{2,5,6},
{7,8,9}
)
comboList =
(
{2,5},
{8,9}
)
I want to zip the above lists to yield the resultant as below - Note that there are 3 results as per FullList and the undelying lists have distinct integers我想压缩上面的列表以产生如下结果 - 请注意,根据 FullList 有 3 个结果,并且底层列表具有不同的整数
finalList =
{
{1,2,3,8,9},
{2,5,6,8,9},
{7,8,9,2,5}
}
Okay, it sounds like you might want something like:好的,听起来你可能想要这样的东西:
var result = fullList
.Select(original =>
// We want the original sublist...
original
// concatenated with...
.Concat(
// ... any comboList element
comboList
// which is completely distinct from "original"
.Where(cl => !original.Intersect(cl).Any())
// ... flattening all such comboLists
.SelectMany(cl => cl))
.ToList())
.ToList();
Here's a complete example:这是一个完整的例子:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var fullList = new[]
{
new[] { 1, 2, 3 },
new[] { 2, 5, 6 },
new[] { 7, 8, 9 }
};
var comboList = new[]
{
new[] { 2, 5 },
new[] { 8, 9 }
};
var result = MergeCombinations(fullList, comboList);
foreach (var item in result)
{
Console.WriteLine(string.Join(", ", item));
}
}
static List<List<T>> MergeCombinations<T>(
IEnumerable<IEnumerable<T>> fullList,
IEnumerable<IEnumerable<T>> comboList)
{
var result = fullList
.Select(original =>
// We want the original sublist...
original
// concatenated with...
.Concat(
// ... any comboList element
comboList
// which is completely distinct from "original"
.Where(cl => !original.Intersect(cl).Any())
// ... flattening all such comboLists
.SelectMany(cl => cl))
.ToList())
.ToList();
return result;
}
}
var fullList = new List<List<int>>()
{
new List<int>() {1,2,3},
new List<int>() {2,5,6},
new List<int>() {7,8,9}
};
var comboList = new List<List<int>>()
{
new List<int>() {2,5},
new List<int>() {8,9},
};
fullList.ForEach(i =>
{
comboList.ForEach(j =>
{
if (i.All(x => !j.Contains(x)))
{
i.AddRange(j);
return;
};
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.