我有一个像这样的嵌套词典
Dictionary<double, Dictionary<double, List<string>>>
使用LINQ我想
按降序对外部词典进行排序,保留前20个,并使用内部词典。
按降序对内部词典进行排序,保留已排序的List<string>
并对这些字符串列表执行操作。
我尝试了很多事情但没有成功。
答案 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;