是通用列表独特的
本文关键字:列表 | 更新日期: 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
,因为它更清楚地说明了它将采用这种方式进行比较的材料类型。