【问题标题】:C# Linq 2 Dimensional List FilterC# Linq 2 维列表过滤器
【发布时间】: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}} 的预期结果是什么?
  • 无论如何,我很高兴你得到了答案,但只知道这个问题有点残忍,变成了猜谜游戏。当您提出这样的问题时,请尝试非常具体

标签: c# list linq


【解决方案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() 从平面版本中删除重复值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    相关资源
    最近更新 更多