public Material
{
public MaterialType MaterialKind {get;set;}
}
enum MaterialType
{
Iron,
Plastic,
Carbon,
Wood
}
我有一个材料项目列表。
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。??
上述样品至少有一个副本,即&#34; Iron&#34;因此返回值必须为假。
答案 0 :(得分:5)
像这样(Linq):
bool isItemsListDistinct = !materials
.GroupBy(item => item)
.Any(chunk => chunk.Skip(1).Any());
说明:chunk.Count() > 1
可能带来开销(假设Count()
返回 1234567 ,内部表示是链接列表< / em>),所以更安全的方法是检查第一个之后是否有一个项目:chunk.Skip(1).Any()
。
编辑:即使 Linq to Objects 中GroupBy()
的当前实现没有Count()
出现问题:
http://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,7bb231e0604c79e3
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()
当集合/(可能)依赖于实现时是一种很好的做法。
答案 1 :(得分:3)
这是一种解决方法:
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()
扩展名不会在任何其他环境中编译)
代码基本上按材料类型分组,然后询问是否可以多次找到任何分组的条目。
请注意,您应该将您的方法命名为更具代表性的方法,例如IsListDistinctByMaterialType
,因为它更清楚地表明它将采用材料类型进行比较。
答案 2 :(得分:3)
更快的方法是:
var materialsSeen = new HashSet<MaterialType>();
var allDifferent = items.All(i => materialsSeen.Add(i.MaterialKind));
一旦看到重复的材料,就会停止,而不是读取整个输入以便对其进行分组。