如何在KeyDictionary变量

时间:2018-04-26 15:41:36

标签: c# linq

所以我有一组具有多个属性的对象,其中两个是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 =住宅列表中所有唯一名称的列表

  • 在不同的群组上可以出现相同的名称

希望有人可以帮我进一步! 提前谢谢!

3 个答案:

答案 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());