C#自定义列表基于属性的重复值

时间:2013-11-05 14:09:34

标签: c#

我有一个自定义列表类,比方说,

public class Fruit
{
    public string Name { get; set; }
    public string Size { get; set; }
    public string Weight{ get; set; }
}

现在我正在向它添加记录,

 List<Fruit> Fruits= new List<Fruit>();

 //some foreach loop 
 Fruit fruit = new Fruit();
 fruit.Name = ...;
 fruit.Size = ...;
 fruit.Weight = ...;

 Fruits.Add(fruit);

我想要什么?

我希望对Public Fruit Class进行更改,以便检查自定义列表中的任何水果是否已经具有相同的权重,然后忽略它并继续例如不要将它添加到列表中。

我更愿意这样做而不改变foreach循环逻辑

3 个答案:

答案 0 :(得分:7)

使用LINQ .Any() - 确定序列的任何元素是否存在或满足条件。 (MSDN:http://msdn.microsoft.com/en-us/library/system.linq.enumerable.any.aspx

if (!Fruits.Any(f => fruit.Weight != null && f.Weight == fruit.Weight))
   Fruits.Add(fruit);

答案 1 :(得分:1)

如果不允许重复的权重,我会使用HashSet<Fruit>与自定义IEqualityComparer

public class FruitWeightComparer : IEqualityComparer<Fruit>
{
    public bool Equals(Fruit x, Fruit y)
    {
        if(x == null || y== null) return false;
        if (Object.ReferenceEquals(x, y)) return true;
        return x.Weight == y.Weight;
    }

    public int GetHashCode(Fruit obj)
    {
        return obj.Weight == null ? 0 : obj.Weight.GetHashCode();
    }
}

现在您可以将HashSet constructor与此比较器一起使用:

HashSet<Fruit> Fruits = new HashSet<Fruit>(new FruitWeightComparer());
// ...
bool notInSet = Fruits.Add(fruit); 
如果可以添加项目,

HashSet.Add将返回true。

答案 2 :(得分:0)

您可以在插入时控制它,只需不插入已有的水果

即可
if (!myFruits.Any(f => f.Weight == newFruit.Weight))
   myFruits.Add(newFruit);

如果你无法操纵插入逻辑,你可以创建一个包含正常List<T>的自定义列表,并改变Add的行为,如上例所示:

public class FruitsWithDistinctWeightList : IEnumerable<Fruit>
{  
    private List<Fruit> internalList;

    ... // Constructor etc.

    public void Add(Fruit fruit)
    {
       if (!internalList.Any(f => f.Weight == fruit.Weight))
         internalList.Add(fruit);
    }       

    ... // Further impl of IEnumerable<Fruit> or IList<Fruit>
}

您还可以使用一些不允许重复项目的现有集合。例如,一些基于散列的集合,例如HashSet<Fruit>

var fruitsWithDistinctWeight = new HashSet<Fruit>(new FruitWeightComparer());

你使用的比较器说同等重量的水果是相同的:

public class FruitWeightComparer : IEqualityComparer<Fruit>
{
   public bool Equals(Fruit one, Fruit two)
   {
        return one.Weight == two.Weight;
   }

   public int GetHashCode(Fruit item)
   {
        return one.Weight.GetHashCode();
   }
}

请注意,HashSet<T>不像列表那样排序。请注意,为简单起见,上面的所有代码都假设已设置Weight字段。如果你的班级有公共制定者(即不保证这一点),你必须适当改变。