C# Linq 2 维列表过滤器
Posted
技术标签:
【中文标题】C# Linq 2 维列表过滤器【英文标题】:C# Linq 2 Dimensional List Filter 【发布时间】:2021-10-29 00:54:09 【问题描述】:编辑 - 感谢@Monofuse:
List<List<int>> list1,
list2,
list2_flattened = list2.SelectMany(x => x).ToList(); // 1d list
list1 = list1.Select(x => x.Where(y => !list2_flattened.Contains(y)).ToList()).ToList(); // 2d list (definitely not the most efficient function, but my list is constrained to a size of about 20)
鉴于 2 个列表:
List<List<int>> list1;
List<List<int>> list2;
您将如何过滤 List1 中的项目,以便最终得到 list2 中不存在的项目?
忘了说:list1 必须保持原来的结构(即 List,所以 SelectMany 不是一个选项)
我正在寻找 linq 解决方案
谢谢!
【问题讨论】:
到目前为止你尝试过什么?你能分享你当前的代码尝试吗? 你能添加一个正负匹配的例子吗? @rkrahl 顺序重要吗? 你有2套套,“不存在”的定义是什么?List1 = 1,2,3,4,5,6
和 List2 = 1,3,6,5,4
的预期结果是什么?
无论如何,我很高兴你得到了答案,但只知道这个问题有点残忍,变成了猜谜游戏。当您提出这样的问题时,请尝试非常具体
【参考方案1】:
如果我对您的理解正确,并且您想排除 list2
int
值来自list1
,您可以输入
var result = list1
.Select(list => list
.Where(item => !list2
.SelectMany(dropList => dropList)
.Any(drop => drop == item))
.ToList())
.ToList();
例如
List<List<int>> list1 = new List<List<int>>()
new List<int>() 1, 2, 2, 3, 3, 4, 4,
new List<int>() 2,,
new List<int>() 5, 6,
;
// We should remove 2, 5, 3 whenever they appear in list1
List<List<int>> list2 = new List<List<int>>()
new List<int>() 2, 5,
new List<int>() 3, 3,
;
var result = list1
.Select(list => list
.Where(item => !list2
.SelectMany(dropList => dropList)
.Any(drop => drop == item))
.ToList())
.ToList();
string report = string.Join(Environment.NewLine, result
.Select(line => $"[string.Join(", ", line)]"));
Console.Write(report);
结果:
[1, 4, 4]
[]
[6]
【讨论】:
【参考方案2】:不确定是否要删除其中不再有任何内容的 list1 列表。也不确定您是否要检查子列表中的每个项目是否与 list2 的所有子列表匹配。
var list1 = new List<List<int>>();
var list2 = new List<List<int>>();
var flatList2 = list2.SelectMany(l2 => l2).Distinct();
var result = list1
.Select(o => o
.Where(inner => !flatList2.Contains(inner)))
.Where(o => o.Any());
下面的完全一样,只是变量名不同。我认为这可能有助于人们了解更多。由于我们处理的是一个二维数组,我总是觉得把它想象成一个表格会更容易一些。
var table = new List<List<int>>();
var table2 = new List<List<int>>();
var distinctColumns = table2.SelectMany(row => row).Distinct();
var result = table
.Select(row => row
.Where(column => !distinctColumns.Contains(column)))
.Where(row => row.Any());
【讨论】:
谢谢!这很棒!澄清一下-我只对过滤匹配的整数感兴趣(因此,如果 list1 中的任何项目存在于 list2 中的任何列表中->该项目将被排除)另外,将 list2 展平一次不是更好吗(在过滤项目之前),而不是为每个内部项目都这样做? "list2.SelectMany(l2 => l2)" - 这可以在上面声明为不在每次迭代中执行此操作。 我们也可以 distinct() 从平面版本中删除重复值以上是关于C# Linq 2 维列表过滤器的主要内容,如果未能解决你的问题,请参考以下文章