C# 使用LINQ查询字典中的字典

C# 使用LINQ查询字典中的字典,c#,linq,C#,Linq,我有一本这样的嵌套字典 Dictionary<double, Dictionary<double, List<string>>> 字典 我想和林克一起 按降序排列外部字典,保留前20个,然后使用内部字典 按降序排列内部字典,保留已排序的列表,并对这些字符串列表执行操作 我尝试了很多东西,但都没有成功。字典不是为分类而设计的 也就是说,这个问题包含了许多不同的词典排序策略。 您可以使用2个SortedDictionary,并在键上迭代,而无需使用LINQ。字

我有一本这样的嵌套字典

Dictionary<double, Dictionary<double, List<string>>>
字典
我想和林克一起

  • 按降序排列外部字典,保留前20个,然后使用内部字典

  • 按降序排列内部字典,保留已排序的
    列表
    ,并对这些字符串列表执行操作


  • 我尝试了很多东西,但都没有成功。

    字典不是为分类而设计的

    也就是说,这个问题包含了许多不同的词典排序策略。

    您可以使用2个SortedDictionary,并在键上迭代,而无需使用LINQ。

    字典
    实现了
    IEnumerable
    ,允许对双/值对进行查询:

    Dictionary<double, Dictionary<double, List<string>>> dict = GetDict();
    
    IEnumerable<Dictionary<double, List<string>>> top20 = (
        from kvp in dict
        orderby kvp.Key descending
        select kvp.Value
        ).Take(20);
    
    IEnumerable<List<string>> res =
        from d in top20
        from kvp in d
        orderby kvp.Key descending
        select kvp.Value;
    
    Dictionary dict=GetDict();
    IEnumerable top20=(
    来自dict中的kvp
    orderby kvp.Key递减
    选择kvp.Value
    ).采取(20);
    数列=
    从排名前20的d开始
    来自d中的kvp
    orderby kvp.Key递减
    选择kvp.Value;
    
    一条长线

    var result = dict.OrderByDescending(outer => outer.Key).Take(20).SelectMany(x =>
        x.Value).OrderByDescending(inner => inner.Key).Select(i => i.Value);
    

    为了测试这类东西,我强烈推荐[LINQPad][1],它对于没有自动完成的版本是免费的。 我首先用测试数据填充数据:

    Dictionary<double, Dictionary<double, List<string>>> master
         = new Dictionary<double, Dictionary<double, List<string>>>();
    
    for( double i = 1; i < 5; i += 0.25 )
    {
        master[ i ] = new Dictionary<double, List<string>>();
        for( double j = 1; j < 5; j += 0.25 )
        {
            master[ i ][ j ] = new List<string>();
            master[ i ][ j ].Add( String.Format( "{0}-{1}a", i, j ) );
            master[ i ][ j ].Add( String.Format( "{0}-{1}b", i, j ) );
            master[ i ][ j ].Add( String.Format( "{0}-{1}c", i, j ) );
        }
    }
    
    接下来我得到前2名(对于您的数据,您当然想要前20名,我只是使用了一个较小的测试集)

    现在我将其用作下一个查询的源:

    var query2 = from di2 in query1.Take(2)
                from item in di2.Valuefrom di in master
                orderby di.Key descending
                select di
                orderby item.Key descending
                select item;
    // show output
    query2.Dump("Merged list");
    
    您可能已经意识到,您可以通过一个查询完成这一切:

    var query = from di2 in (
                    from di in master
                    orderby di.Key descending
                    select di
                ).Take(2)
                from item in di2.Value
                orderby item.Key descending
                select item;
    
    最后,这只是您想对列表执行什么操作的问题,如果您只想让字符串按每个父项的自然顺序排列,请执行以下操作:

    var stringList = from di in query
                    from s in di.Value
                    select s;
    stringList.Dump("Strings only");
    
    对于我的测试数据,这里是我得到的前十几项(不想列出所有96项结果):

    因为我只做了前2个,而不是前20个,所以我先得到了4.5和4.75键的项目,然后在其中我按第二个键排序,得到了所有值。

    尝试使用“代码”格式,会使您的问题更具可读性。基本上是代码前后的一个空行,代码缩进4个空格(或者只使用工具栏上的按钮)。
    var query = from di2 in (
                    from di in master
                    orderby di.Key descending
                    select di
                ).Take(2)
                from item in di2.Value
                orderby item.Key descending
                select item;
    
    var stringList = from di in query
                    from s in di.Value
                    select s;
    stringList.Dump("Strings only");
    
    4.75-4.75a
    4.75-4.75b
    4.75-4.75c
    4.5-4.75a
    4.5-4.75b
    4.5-4.75c
    4.75-4.5a
    4.75-4.5b
    4.75-4.5c
    4.5-4.5a
    4.5-4.5b
    4.5-4.5c