所以我有一组具有多个属性的对象,其中两个是groupname和personname。现在我需要在集合中计算每个对象有多少属于某个组和人。换句话说,我需要按groupname,然后是personname进行分组,然后计算有多少个对象具有此组合。首先我创建了这个
public MultiKeyDictionary<string, string, int> GetPersonsPerGroup(IEnumerable<Home> homes ,List<string> gr, List<string> na)
{
List<string> groups = gr;
groups.Add("");
List<string> names = na;
names.Add("");
List<Home> Filtered = homes.ToList();
Filtered.ForEach(h => h.RemoveNull());
var result = new MultiKeyDictionary<string, string, int>();
int counter1 = 0;
foreach (var g in groups)
{
int counter2 = 0;
foreach (var n in names)
{
int counter3 = 0;
foreach (Home h in Filtered)
{
if (h.GroupName == g && h.PersonName == n)
{
counter3++;
if (counter3 > 100)
break;
}
}
if (counter3 > 0)
{
result.Add(g,n,counter3);
}
counter2++;
}
counter1++;
}
这可能看起来不错,但问题是“home”参数可以包含超过10000个对象,超过1500个唯一名称和大约200个唯一组。这导致迭代次数达到十亿次,真正减慢了我的程序速度。所以我需要另一种处理方式。这让我决定尝试使用linq。这导致了这一创造:
var newList = Filtered.GroupBy(x => new { x.GroupName, x.PersonName })
.Select(y => (MultiKeyDictionary<string, string, int>)result.Add(y.Key.GroupName, y.Key.PersonName, y.ToList().Count));
哪个错误"Cannot convert type '
无法' to 'MultiKeyDictionary<string,string,int>'
,我不知道如何解决它。我怎样才能使这个查询的结果存储在一个MultikeyDictionary中,而不必遍历每个可能的组合并计算所有组合。
一些信息:
MultiKeyDictionary
是我定义的类(实际上我在这里找到的),它只是一个普通的字典,但有两个键与一个值相关联。
Home对象上的RemoveNull()
方法确保Home对象的所有属性都不为null。如果是这种情况,则值设置为null
("null", basic date, 0, ...
)。
参数是:
homes = a
从其他类接收的Home对象列表
gr =住宅列表中所有唯一群组的列表
na =住宅列表中所有唯一名称的列表
在不同的群组上可以出现相同的名称
希望有人可以帮我进一步! 提前谢谢!
答案 0 :(得分:0)
Select
必须返回一些内容。您没有返回,只是添加到现有列表。这样做:
var newList = Filtered.GroupBy(x => new { x.GroupName, x.PersonName }):
var result = new MultiKeyDictionary<string, string, int>);
foreach(var y in newList)
{
result.Add(y.Key.GroupName, y.Key.PersonName, y.ToList().Count));
}
您收到错误的原因如下:
&#34;无法转换类型&#39; void&#39; to&#39; MultiKeyDictionary&#39;
是因为您试图将Add
的{{1}}返回值转换为void
,这显然无法完成。
答案 1 :(得分:0)
如果MultiKeyDictionary需要匹配两个键才能找到结果,那么您可能只想使用带有元组的常规Dictionary
作为复合类型。 C#7具有使这非常简单的功能:
public Dictionary<(string, string), int> GetPersonsPerGroup(IEnumerable<Home> homes ,List<string> gr, List<string> na)
{
return Filtered.GroupBy(x => (x.GroupName, x.PersonName))
.ToDictionary(g => g.Key, g => g.Count);
}
您甚至可以将可选的编译时名称与元组的值相关联,方法如下:Dictionary<(string groupName, string personName), int>
。
答案 2 :(得分:0)
您的分组密钥匿名对象应该可以作为标准Dictionary
密钥使用,因此没有理由创建新类型Dictionary
,除非它通过单个密钥提供特殊访问权限,因此只需将分组转换为标准Dictionary
:
var result = Filtered.GroupBy(f => new { f.GroupName, f.PersonName })
.ToDictionary(fg => fg.Key, fg => fg.Count());