筛选并保留属性匹配的对象列表中的第一个对象

本文关键字:对象 列表 一个对象 保留 属性 筛选 | 更新日期: 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实现。