linq C#提取,从源代码中删除尽可能多的记录

pbgvytdp  于 2023-11-14  发布在  C#
关注(0)|答案(3)|浏览(107)

我们有两个数组

int[] arr1 = new int[] { 1, 1, 1, 2, 3 };
int[] arr2 = new int[] { 1, 2 };

字符串
我正在寻找Linq(不必要)方法,接受这两个集合,并返回

{ 1, 1, 3 }


问题是Intersect返回{ 3 }

nue99wik

nue99wik1#

您可以计算要删除的项的频率(arr2),然后从arr1中删除它们

var freq = arr2
  .GroupBy(item => item)
  .ToDictionary(group => group.Key, group => group.Count());

var result = arr1
  .Where(item => !freq.ContainsKey(item) || --freq[item] >= 0)
  .ToArray();

字符串

kzmpq1sx

kzmpq1sx2#

尝试从第一个数组中删除第二个数组中的所有项目:

var a1 = new List<int> { 1, 1, 1, 2, 3 };
var a2 = new List<int> { 1, 2 };
a2.ForEach(x => a1.Remove(x));

字符串

oug3syen

oug3syen3#

如果你真的想要只使用LINQ的解决方案:计算两者的频率,然后从第二个列表中跳过相应的项目计数来重建列表。如果你想改变顺序,基于原始索引重新排序是一个选择.但在这一点上,我只需要在没有LINQ的情况下过滤列表。

var a1 = new List<int> { 1, 1, 1, 2, 3 };
var a2 = new List<int> { 1, 2 };
var second = a2.GroupBy(x=>x).ToDictionary(g=>g.Key, g=> g.Count()); 
var result = a1.GroupBy(x=>x)
   .SelectMany(g => g.Skip(second.ContainsKey(g.Key)? second[g.Key] : 0));

字符串
我会选择过滤(同样,MichaelTurczyn基于移除的answer更容易阅读,尽管由于O(len_list_one * len_list_two)性质,对于大型列表可能太慢)。
下面的代码是O(len_list_one + len_list_two),并保持第一个列表的顺序:

var second = a2.GroupBy(x=>x).ToDictionary(g=>g.Key, g=> g.Count()); 
var result = new List<int>();
foreach(var x in a1)
{
   if (second.TryGetValue(x, out var count) && count > 0)
   {
      second[x] --;
   }
   else
   {
     result.Add(x);
   }
}

相关问题