使用LINQ查询字典中的字典

时间:2009-10-09 00:18:18

标签: c# linq

我有一个像这样的嵌套词典

Dictionary<double, Dictionary<double, List<string>>>

使用LINQ我想

  1. 按降序对外部词典进行排序,保留前20个,并使用内部词典。

  2. 按降序对内部词典进行排序,保留已排序的List<string>并对这些字符串列表执行操作。

  3. 我尝试了很多事情但没有成功。

5 个答案:

答案 0 :(得分:5)

一条长线。

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

答案 1 :(得分:1)

为了测试这种东西,我强烈推荐[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 ) );
    }
}

LINQPad允许我使用它的自定义Dump()扩展方法转储到输出(在这种情况下,我将我的类型设置为“C#Statement(s)”):

master.Keys.Dump("Master keys");

接下来我获得前2名(对于你的数据当然你想要前20名,我只是使用较小的一组进行测试)。

var query1 = from di in master
            orderby di.Key descending
            select di;
query1.Take(2).Dump("Top 2 dictionaries (by key desc)");

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

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个结果):

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

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

答案 2 :(得分:0)

字典不是为了排序而设计的。

这样说,这个问题包含了许多不同的字典排序策略。 How do you sort a dictionary by value?

答案 3 :(得分:0)

您可以使用2个SortedDictionary,并在不使用LINQ的情况下迭代键。

答案 4 :(得分:0)

Dictionary<TKey, TValue>实现IEnumerable<KeyValuePair<TKey, TValue>>,允许针对您的双/值对进行查询:

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;