我有两个相同类型的列表。该类型没有标识符或以编程方式区分的任何其他保证方式。
我希望A中的物品不在B中。
如果类型有标识符,我可以使用如下语句......
var result = listA
.Where(a => listB.Where(b => b.Id == a.Id).Count() == 0)
.ToList();
到目前为止,我能做到这一点的唯一方法是使用循环,我将每个项目添加到原始列表中不出现的次数。
foreach (var val in listB.Select(b => b.val).Distinct())
{
var countA = listA.Where(a => a.val == val).Count();
var countB = listB.Where(b => b.val == val).Count();
var item = listA.Where(a => a.val == val).FirstOrDefault();
for (int i=0; i<countA-countB; i++)
result.Add(item);
}
有没有更清洁的方法来实现这一目标?
修改: 这是列表中对象的简化版本。它来自一个正在击中另一个系统的Web服务。
public class myObject
{
public DateTime SomeDate { get; set; }
public decimal SomeNumber; { get; set; }
public bool IsSomething { get; set; }
public string SomeString { get; set; }
}
我收到的数据对于SomeDate / SomeString具有相同的值,并且SomeNumber和IsSomething的值重复。两个对象可能具有相同的属性,但我需要将它们视为不同的对象。
答案 0 :(得分:9)
试试这个:
var listA = new List<Int32> {1, 2, 2, 3, 5, 8, 8, 8};
var listB = new List<Int32> {1, 3, 5, 8};
var listResult = new List<Int32>(listA);
foreach(var itemB in listB)
{
listResult.Remove(itemB);
}
答案 1 :(得分:1)
我错过了什么?
class Program { static void Main(string[] args) { List<int> a = new List<int>(); a.Add(1); a.Add(2); a.Add(2); a.Add(3); a.Add(5); a.Add(8); a.Add(8); a.Add(8); List<int> b = new List<int>(); b.Add(1); b.Add(3); b.Add(5); b.Add(8); foreach (int x in b) a.Remove(x); foreach (int x in a) Console.WriteLine(x); Console.ReadKey(false); } }
答案 2 :(得分:0)
您可以对两个列表进行排序,然后同时迭代它们。
public IEnumerable<int> GetComplement(IEnumerable<int> a, IEnumerable<int> b)
{
var listA = a.ToList();
listA.Sort();
var listB = b.ToList();
listB.Sort();
int i=0,j=0;
while( i < listA.Count && j < listB.Count )
{
if(listA[i] > listB[j]) {yield return listB[j];j++;}
else if (listA[i] < listB[j]) {yield return listA[i]; i++; }
else {i++;j++;}
}
while(i < listA.Count)
{
yield return listA[i];
i++;
}
while(j < listB.Count)
{
yield return listB[j];
j++;
}
}
我不知道这是否“更干净”,但它应该在大型数据集上更具性能。
答案 3 :(得分:0)
两个列表中的对象是否相同?如果是这样,您可以使用.Where(a => listB.Where(b => b == a).Count() == 0)
或者
.Where(a => !listB.Any(b => b == a))
答案 4 :(得分:0)
这有点令人讨厌,但它可以满足您的需求。虽然不确定性能。
var a = new List<int> { 1, 2, 2, 3, 5, 8, 8, 8 };
var b = new List<int> { 1, 3, 5, 8 };
var c = from x in a.Distinct()
let a_count = a.Count(el => el == x)
let b_count = b.Count(el => el == x)
from val in Enumerable.Repeat (x, a_count - b_count)
select val;
答案 5 :(得分:0)
为什么不为myObject
:
public class YourTypeEqualityComparer : IEqualityComparer<myObject>
{
public bool Equals(myObject x, myObject y)
public int GetHashCode(myObject obj)
}
然后像这样使用它:
var list1 = new List<myObj>();
var list2 = new List<myObj>()
list1.RemoveAll(i =>
list2.Contains(list1),
new YourTypeEqualityComparer()
);
现在list1
包含结果。