我有一个
ObservableCollection<BasicClass> allCollection;
ObservableCollection<BasicClass> selectedCollection;
,其中
BasicClass
{
public Name {get;set;}
public Age {get;set;}
}
现在我向BasicClass
添加了多个allCollection
项,并且只选择了BasicClass
到selectedCollection
SomeWhere我想在selectedCollection
中添加allCollection
中没有的项目。
我试过这个
foreach(var a in allCollection)
{
foreach(var s in selectedCollection)
if(a.Name!=s.Name)
//selectedCollection.Add(new BasicClass {Name =a.Name, Age=a.Age});
}
但问题是这段代码为每个不匹配的名称添加了新的BasicClass, 但我的实际要求是,对于allCollection的每个Name,比较所有selectedCollection项。如果不存在,则为下一个项目添加其他移动。
LINQ解决方案有助于此吗?实际上我通过更多的if和旗帜实现了这一点,但这看起来很忙。 我的传统解决方案
foreach(var a in allCollection)
{
bool same = false;
foreach(var s in selectedCollection)
if(a.Name==s.Name)
same=true;
}
if(same==false)
selectedCollection.Add(new BasicClass {Name =a.Name, Age=a.Age});
我讨厌这个..
编辑:
我不希望比较集合到集合。 我想将collection1值与collection2的所有值进行比较,如果不存在,那么我想添加
答案 0 :(得分:1)
我不确定我是否理解你的要求,所以我可能会忽略这一点......
您的BasicClass
应该实现IEquatable<BasicClass>
接口,以便可以比较BasicClass
的两个实例是否相等:
class BasicClass : IEquatable<BasicClass>
{
public Name {get;set;}
public Age {get;set;}
public bool Equals(BasicClass other)
{
if (other == null)
return false;
return string.Equals(this.Name, other.Name);
}
public override int GetHashCode()
{
return Name == null ? 0 : Name.GetHashCode();
}
}
现在,您可以使用Except
方法查找allCollection
但不在selectedCollection
中的项目:
BasicClass[] notSelected = allCollection.Except(selectedCollection).ToArray();
foreach(BasicClass item in notSelected)
{
selectedCollection.Add(item);
}
或者,您可以实施IEqualityComparer<BasicClass>
并将其传递给Except
(而不是在IEquatable<BasicClass>
中实施BasicClass
)
答案 1 :(得分:1)
所以基本上你需要'where-not-in'? Linq-&gt;除了是要去的方法,过滤BasicClass.name只实现IEqualityComparer for Except。
答案 2 :(得分:1)
你确定你不需要这个吗?
foreach(var a in allCollection)
{
if (!selectedCollection.Contains(a))
selectedCollection.Add(new BasicClass {Name =a.Name, Age=a.Age});
}
修改强>
我刚才看到你的评论只是关于名字上的匹配,所以上面并不是你想要的:)。请尝试这种方法:
foreach(var a in allCollection)
{
if (!selectedCollection.Any(s => a.Name == s.Name))
{
selectedCollection.Add(new BasicClass {Name =a.Name, Age=a.Age});
}
}
修改强>
正如克里斯建议你也可以使用“除外”来创建一个集合。我不确定这会获得多少收益,它可能会更快,但它涉及编写比较器代码并创建一个新的临时集合。但是,它非常简洁。一旦您编写了比较器,您只需要将此缺失的项目添加到集合中:
selectedCollection.Concat(allCollection.Except(selectedCollection));
答案 3 :(得分:0)
你是对的,Linq更容易实现这一点:
var itemsToAdd = allCollection.Except(selectedCollection);
foreach (var item in itemsToAdd)
selectedCollection.Add(item);
另一方面,这只是使两个列表包含完全相同的项目。当然这就是你想要的?
如果BasicItem根据Name覆盖'Equals'和'GetHashCode',那么这就是您所需要的。如果没有,那么您还需要实现IEqualityComparer:
//Allows us to compare BasicItems as if Name is the key
class NameComparer: IEqualityComparer<BasicItem>
{
public bool Equals(BasicItem first, BasicItem second)
{
return first.Name == second.Name;
}
public int GetHashCode(BasicItem value)
{
return value.Name.GetHashCode;
}
}
现在,您将此类的实例传递给Except
:
var itemsToAdd = allCollections.Except(selectedCollection, new NameComparer());