我有2个对象列表,我想从第一个对象中获取所有对象,其中字符串a与第二个列表中的字符串a不匹配。
public class ObjectA
{
string Item;
int b;
}
public class ObjectB
{
string Item;
int b;
}
使用linq可以很容易地做到这一点,但是更快的方法是什么?
var newList = objectAList.Where(a => !objectBList.Any(b => b.Item == a.Item)).ToList()
答案 0 :(得分:1)
这怎么办-没有linq,仍然不错且流利,为正确的类型进行了编辑:
ObjectBList.RemoveAll(p => ObjectAList.Find(p2 => p2.Item == p.Item) != null ? true : false);
完整示例:
public class ObjectBase {
public string Item;
public int b;
}
public class ObjectA : ObjectBase{ }
public class ObjectB : ObjectBase { }
public List<ObjectB> Testing() {
var list1 = new List<ObjectA> { new ObjectA { Item = "str1", b = 0 } };
var list2 = new List<ObjectB> { new ObjectB { Item = "str1", b = 0 }, new ObjectB { Item = "str2", b = 1 } };
// Key Line - Remove all from list2 found in list1
list2.RemoveAll(p => list1.Find(p2 => p2.Item == p.Item) != null ? true : false);
return list2;
}
答案 1 :(得分:1)
Linq Except方法就是为此目的而设计的,并且速度非常快。但是,您会感到皱纹,您的两个类具有兼容的字段,但却是不同的对象。这是处理它的一种方法:
class ObjectBase
{
public string Item;
public int b;
}
class ObjectA : ObjectBase
{
}
class ObjectB : ObjectBase
{
}
class ObjectComparer : IEqualityComparer<ObjectBase>
{
public bool Equals(ObjectBase a, ObjectBase b)
{
return a?.Item == b?.Item;
}
public int GetHashCode(ObjectBase o)
{
return o.?Item?.GetHashCode() ?? 0;
}
}
// Very fast compared to your current approach. 1000x for my test case.
var newList = objectAList.Except(objectBList, new ObjectComparer()).ToList();
答案 2 :(得分:0)
您可以尝试以下代码:
public static void Main(string[] args)
{
List<ObjectA> listA = new List<ObjectA>()
{
new ObjectA(){Item = "abc" },
new ObjectA(){Item = "ab" },
};
List<ObjectB> listB = new List<ObjectB>()
{
new ObjectB(){Item = "abc" },
};
// loop backwards removing entry if it is found in the other list
for (int i = listA.Count - 1; i >= 0; i--)
if (listB.Find(e => e.Item == listA[i].Item) != null)
listA.RemoveAt(i);
}
我(您和我的)两种方法都运行了五次,并在毫秒内得到以下结果(每次循环重复算法,100000次迭代):
我的方法:107 46 94 67 91
您的方法:108267171138173
这也可能是由于额外的ToList()
调用和创建新对象newList
造成的。
因此,总而言之,如果有任何改进,那几乎没有什么改进,我不会为此而牺牲出色的LINQ方法提供的可读性。
此外,它们在内部被设计为尽可能快地工作,所以我会依靠它们:)
答案 3 :(得分:0)
最快的方法是:
var newList = objectAList.Select(a => a.Item).Except(objectBList.Select(b => b.Item));
是的,我知道这是Linq,但是您要求一种更快的方法:)
HTH
答案 4 :(得分:0)
时间上最快的方法是使用HashSet <>,尤其是对于大型列表:
private List<ObjectA> Find(List<ObjectA> list1, List<ObjectB> list2)
{
var list2HashSet = list2.Select(x => x.Item).ToHashSet();
return list1.Where(x => !list2HashSet.Contains(x.Item)).ToList();
}
注意:,不要忘记将属性Item
设为公开,否则它将无法正常工作!