过滤并保留具有匹配属性的对象列表的第一个对象

时间:2013-02-15 17:29:51

标签: c# .net entity-framework

我在前面道歉,因为我现在意识到我完全把我的例子措辞错了。对于那些做出回应的人,我真的很感激。请让我重新尝试解释更准确的细节。请编辑您的回复,我再次道歉,因为我之前的帖子没有更准确。

使用名为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],并从data[6]中移除data[7]List<Staging>

修改 我有以下代码可以使用,但还有其他方法吗?

  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);
    }
  }

4 个答案:

答案 0 :(得分:2)

您可以通过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的第一个“匹配”值。

答案 1 :(得分:0)

你可以使用Linq:

var result = (from my in theList where my.Var3 == "Foo" select my).First();

如果 想要保留其他项目,则可以使用Distinct()代替First()。要使用Dictinct(),MyClass必须实现IEquatable<T>,或者您必须提供IEqualityComparer<T>,如MSDN链接中所示。

答案 2 :(得分:0)

var uniques = (from theList select theList.Var3).Distinct();

这将为您提供所有条目的不同值。

答案 3 :(得分:0)

“规范”的方法是将适当实施的比较器传递给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 overload - 它只是假设Default比较器,如果由{{1}实现,它将使用IEquatable<T> }。