给定数据结构:
class TheClass
{
int NodeID;
double Cost;
List<int> NodeIDs;
}
包含数据的列表:
27 -- 10.0 -- 1, 5, 27
27 -- 10.0 -- 1, 5, 27
27 -- 10.0 -- 1, 5, 27
27 -- 15.5 -- 1, 4, 13, 14, 27
27 -- 10.0 -- 1, 4, 25, 26, 27
27 -- 15.5 -- 1, 4, 13, 14, 27
35 -- 10.0 -- 1, 4, 13, 14, 35
我想将其缩减为唯一的NodeID列表
27 -- 10.0 -- 1, 5, 27
27 -- 15.5 -- 1, 4, 13, 14, 27
27 -- 10.0 -- 1, 4, 25, 26, 27
35 -- 10.0 -- 1, 4, 13, 14, 35
然后我将总结成本列(节点27总成本:10.0 + 15.5 + 10.0 = 35.5) - 该部分是直接的。
删除重复行/查找唯一身份的最快方法是什么?
生产数据集将具有100到200个ID的NodeID列表,列表中大约1,500个,其中大约500个是唯一的。
我100%专注于速度 - 如果添加一些其他数据会有所帮助,我很高兴(我已经尝试将列表哈希到SHA值,但结果变慢了比我现在的咕噜声详尽的搜索。)
答案 0 :(得分:3)
.GroupBy(x=> string.Join(",", x.NodeIDs)).Select(x=>x.First())
大数据应该比区别更快。
答案 1 :(得分:2)
如果您想根据相同的列表删除重复的对象,可以为列表创建自定义IEqualityComparer<T>
并将其用于Enumerable.GroupBy
。然后,您只需为每个组创建班级的新实例,并总结Cost
。
这是一个可能的实现(from):
public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
public bool Equals(List<T> lhs, List<T> rhs)
{
return lhs.SequenceEqual(rhs);
}
public int GetHashCode(List<T> list)
{
unchecked
{
int hash = 23;
foreach (T item in list)
{
hash = (hash * 31) + (item == null ? 0 : item.GetHashCode());
}
return hash;
}
}
}
这是一个选择每个组一个(唯一)实例的查询:
var nodes = new List<TheClass>(); // fill ....
var uniqueAndSummedNodes = nodes
.GroupBy(n => n.NodeIDs, new ListEqualityComparer<int>())
.Select(grp => new TheClass
{
NodeID = grp.First().NodeID, // just use the first, change accordingly
Cost = grp.Sum(n => n.Cost),
NodeIDs = grp.Key
});
nodes = uniqueAndSummedNodes.ToList();
此实现使用SequenceEqual
来考虑列表中每个数字的顺序和出现次数。
修改:我只是看到你不想总结小组Costs
,而是总结所有小组&#39 ; Cost
,这很简单:
double totalCost = nodes.Sum(n => n.Cost);
如果您不想总结该组本身,请替换
...
Cost = grp.Sum(n => n.Cost),
与
...
Cost = grp.First().Cost, // presumes that all are the same