是通用列表独特的

本文关键字:列表 | 更新日期: 2023-09-27 18:06:03

public Material
{
  public MaterialType MaterialKind {get;set;}
}
enum MaterialType
{
   Iron,
   Plastic,
   Carbon,
   Wood
}

我有一个Material项目的列表。

var items = new List<Material>
{ 
  new Material{ MaterialKind = MaterialType.Iron},
  new Material{ MaterialKind = MaterialType.Plastic},
  new Material{ MaterialKind = MaterialType.Carbon},
  new Material{ MaterialKind = MaterialType.Iron},
  new Material{ MaterialKind = MaterialType.Wood},
}

每种类型在材料列表中最多只能有一次可用。

我该怎么写呢:

bool isItemsListDistinct = materials.??

上面的示例至少有一个副本是"Iron",因此返回值必须为false。

是通用列表独特的

像这样(Linq):

bool isItemsListDistinct = !materials
  .GroupBy(item => item)
  .Any(chunk => chunk.Skip(1).Any());

解释:chunk.Count() > 1可能会带来开销(想象Count()返回1234567,内部表示为链表),因此更安全的方法是检查第一个项目之后是否有一个项目:chunk.Skip(1).Any() .

编辑:即使GroupBy()Linq到对象中的当前实现与Count():

没有问题

http://referencesource.microsoft.com/System.Core/系统/Linq/Enumerable.cs, 7 bb231e0604c79e3

  internal class Grouping : IGrouping<TKey, TElement>, IList<TElement> {
    ...
    internal int count;      
    ...
    // No overhead in such implementation
    int ICollection<TElement>.Count {
      get { return count; }
    }
    ...
  }

使用Any(), Exists(在SQL中)等代替Count()当集合是/(可以)依赖于实现是一个很好的做法。

更快捷的方法是:

var materialsSeen = new HashSet<MaterialType>();
var allDifferent = items.All(i => materialsSeen.Add(i.MaterialKind));

一旦看到重复的材料,它就会停止,而不是读入整个输入以对其进行分组。

是这样做的:

void Main()
{
    var items = new List<Material>
    { 
    new Material{ MaterialKind = MaterialType.Iron},
    new Material{ MaterialKind = MaterialType.Plastic},
    new Material{ MaterialKind = MaterialType.Carbon},
    new Material{ MaterialKind = MaterialType.Iron},
    new Material{ MaterialKind = MaterialType.Wood},
    };
    Material.IsItemsListDistinct(items).Dump(); 
}
// Define other methods and classes here
public class Material
{
  public MaterialType MaterialKind {get;set;}
  public static bool IsItemsListDistinct(IList<Material> materialsList) {
    return materialsList.GroupBy(x => x.MaterialKind).Any(x => x.Count() > 1);
  }
}
public enum MaterialType
{
   Iron,
   Plastic,
   Carbon,
   Wood
}

(以上是一个Linqpad示例,因此.Dump()扩展将无法在任何其他环境中编译)

代码本质上按Material Type分组,然后询问是否有任何分组条目可以被发现不止一次。

请注意,您应该将您的方法命名为更具代表性的名称,如IsListDistinctByMaterialType,因为它更清楚地说明了它将采用这种方式进行比较的材料类型。