筛选并保留属性匹配的对象列表中的第一个对象
本文关键字:对象 列表 一个对象 保留 属性 筛选 | 更新日期: 2023-09-27 17:59:39
我提前道歉,因为我现在意识到我的例子完全写错了。对于那些做出回应的人,我真的很感激。请允许我再次尝试用更准确的细节来解释。请编辑你的回复,我再次为我之前的帖子中没有更准确而道歉。
使用一个名为Staging的实体框架模型类(它是我的Staging表的表示形式),我得到了以下List<Staging>
。
List<Staging> data = (from t in database.Stagings select t).ToList();
//check for an empty List...react accordingly...
以下是Staging
的快速外观:
public partial class Staging
{
public int ID { get; set; } //PK
public int RequestID { get; set; } //FK
...
public string Project { get; set; }
...
}
让我们假设查询将10条记录返回到我的data
列表中。我们还假设data[3]
、data[6]
和data[7]
在data.Project
中都具有相同的值,比如说"Foo"
。data.Project
值直到运行时才知道。
既然如此,我该如何保留第一次出现的data[3]
,并从List<Staging>
中删除data[6]
和data[7]
?
编辑:我有以下代码可以工作,但还有其他方法吗?
HashSet<string> projectValuesFound = new HashSet<string>();
List<Staging> newData = new List<Staging>();
foreach (Staging entry in data)
{
if (!projectValuesFound.Contains(entry.Project))
{
projectValuesFound.Add(entry.Project);
newData.Add(entry);
}
}
您可以通过LINQ和HashSet<T>
:来完成此操作
var found = new HashSet<string>();
var distinctValues = theList.Where(mc => found.Add(mc.Var3));
// If you want to assign back into the List<T> again:
// theList = distinctValues.ToList();
这是因为如果值不在集合中,HashSet<T>.Add
将返回true,如果值已经存在,则返回false。因此,您将只获得Var3
的第一个"匹配"值。
var uniques = (from theList select theList.Var3).Distinct();
这将为所有条目提供不同的值。
您可以使用Linq:
var result = (from my in theList where my.Var3 == "Foo" select my).First();
如果也想要保留其他项目,可以使用Distinct()而不是First()。要使用Dicinct(),MyClass
必须实现IEquatable<T>
,或者必须提供一个IEqualityComparer<T>
,如MSDN链接中所示。
"规范"的方法是将适当实现的比较器传递给Distinct:
class Var3Comparer : IEqualityComparer<MyClass> {
public int GetHashCode(MyClass obj) {
return (obj.Var3 ?? string.Empty).GetHashCode();
}
public bool Equals(MyClass x, MyClass y) {
return x.Var3 == y.Var3;
}
}
// ...
var distinct = list.Distinct(new Var3Comparer());
请注意,虽然当前的实现似乎保留了"幸存"元素的顺序,但文档中说它"返回了一个无序的序列",并且最好是这样处理。
还有一个不需要比较器的Distinct重载-它只是假设默认比较器,而默认比较器将使用IEquatable<T>如果由CCD_ 20实现。