C# - 如何从集合视图中获取不同的项目
C# - how to get distinct items from a Collection View
CollectionView view = CollectionView)CollectionViewSource.GetDefaultView(MyData);
View.Filter = i => ((MyClass)i).MyProperty;
我有一个像上面那样的集合视图。问题是已经绑定到列表视图的集合 MyData 包含重复项。我如何获得独特的项目作为我的过滤结果?
你可以试试这个
var g = collection.Select(i => i.Property1).Distinct();
如果有效,请提供反馈。
加上@Sebastian Tam的回答
var g = collection.Select(i => i.Property1).Distinct();
如果集合是来自您自己的用户定义class的序列,您需要为 Distinct 实现 IEquatable 接口以使用默认比较器。
看看这个post
What is the default equality comparer for a set type?
此方法有效:
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(c.Items);
view.Filter = i =>
{
var index1 = c.MyData.FindIndex(delegate (MyClass s)
{
return Object.ReferenceEquals(s, i);
});
var index2 = c.MyData.FindLastIndex(delegate (MyClass s)
{
return ((MyClass)i).MyProperty == s.MyProperty as string; //value comparison
});
return index1 == index2;
};
index1
是对象在集合中的索引。您需要比较 references
才能得到它。
index2
是 value
的最后一个索引。在那里你需要比较value
。
所以你基本上比较当前 element
的 index
是否是它出现的最后一个。
注意:
这不适用于简单类型。我必须像这样初始化我的测试集合:
new List<string>() { new string("I1".ToCharArray()), new string("I1".ToCharArray()), "I2" };
看来我在找出适合您需要的最佳解决方案时来晚了。无论如何,我提供它是因为它比公认的更干净、更快。
首先像往常一样定义一个封装逻辑的函数
static bool IsDuplicate(IEnumerable<MyObject> collection, MyObject target)
{
foreach (var item in collection)
{
// NOTE: Check only the items BEFORE the one in question
if (ReferenceEquals(item, target)) break;
// Your criteria goes here
if (item.MyProperty == target.MyProperty) return true;
}
return false;
}
然后使用它
var view = (CollectionView)CollectionViewSource.GetDefaultView(MyData);
view.Filter = item => !IsDuplicate((IEnumerable<MyClass>)view.SourceCollection, (MyClass)item);
CollectionView view = CollectionView)CollectionViewSource.GetDefaultView(MyData);
View.Filter = i => ((MyClass)i).MyProperty;
我有一个像上面那样的集合视图。问题是已经绑定到列表视图的集合 MyData 包含重复项。我如何获得独特的项目作为我的过滤结果?
你可以试试这个
var g = collection.Select(i => i.Property1).Distinct();
如果有效,请提供反馈。
加上@Sebastian Tam的回答
var g = collection.Select(i => i.Property1).Distinct();
如果集合是来自您自己的用户定义class的序列,您需要为 Distinct 实现 IEquatable 接口以使用默认比较器。
看看这个post
What is the default equality comparer for a set type?
此方法有效:
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(c.Items);
view.Filter = i =>
{
var index1 = c.MyData.FindIndex(delegate (MyClass s)
{
return Object.ReferenceEquals(s, i);
});
var index2 = c.MyData.FindLastIndex(delegate (MyClass s)
{
return ((MyClass)i).MyProperty == s.MyProperty as string; //value comparison
});
return index1 == index2;
};
index1
是对象在集合中的索引。您需要比较 references
才能得到它。
index2
是 value
的最后一个索引。在那里你需要比较value
。
所以你基本上比较当前 element
的 index
是否是它出现的最后一个。
注意:
这不适用于简单类型。我必须像这样初始化我的测试集合:
new List<string>() { new string("I1".ToCharArray()), new string("I1".ToCharArray()), "I2" };
看来我在找出适合您需要的最佳解决方案时来晚了。无论如何,我提供它是因为它比公认的更干净、更快。
首先像往常一样定义一个封装逻辑的函数
static bool IsDuplicate(IEnumerable<MyObject> collection, MyObject target)
{
foreach (var item in collection)
{
// NOTE: Check only the items BEFORE the one in question
if (ReferenceEquals(item, target)) break;
// Your criteria goes here
if (item.MyProperty == target.MyProperty) return true;
}
return false;
}
然后使用它
var view = (CollectionView)CollectionViewSource.GetDefaultView(MyData);
view.Filter = item => !IsDuplicate((IEnumerable<MyClass>)view.SourceCollection, (MyClass)item);