【问题标题】:Sort the dictionary after the value after the key在键之后的值之后对字典进行排序
【发布时间】:2017-05-09 20:44:13
【问题描述】:

我对字典排序有疑问:

SortedDictionary<string, List<int>> mySortedDictionary;

我想用来自 mySortedDictionary 的数据创建新的Dictionary&lt;string,List&lt;int&gt;&gt;,它按值(确切地按列表中的项目数,换句话说 List.Count)升序排序,而 lists.Count 相同,键是按字母升序排序。谁能告诉我如何做到这一点?

mySortedDictionary.Add("orange", List<2,9>) //List.Count = 2
mySortedDictionary.Add("money", List<2,4,8,9>)   //4
mySortedDictionary.Add("monkey", List<2,4,9>)   //3
mySortedDictionary.Add("hokey", List<2,5,9>)   //3

//result: order in new sorted Dictionary//
"orange", List<2,9>
"hokey", List<2,5,9>
"monkey", List<2,4,9>
"money", List<2,4,8,9>

提前感谢您的帮助!!!

【问题讨论】:

  • 字典本身没有任何顺序。即使您想出一种算法以特定顺序插入字典,也不能保证您会以相同的顺序返回它们。
  • @Partha SortedDictionary 有订单(key

标签: c# linq sorting dictionary


【解决方案1】:

SortedDictionary 通过对key 进行排序来存储数据,这是它固有的,即不能被自定义排序替换。因此,如果您想要一个类似Dictionary 的界面,您将必须构建一个自定义数据结构。

如果按排序顺序读取数据的操作会频繁发生,则需要设计一种机制来存储排序后的数据(将排序后的数据和原始数据分开缓存)或以排序方式存储数据。请记住,字典中的Value 可能会在数据结构的生命周期内发生变化,因此您可能需要重新排序数据。这可能不是一个简单的练习。

但是如果你真的想要一个一般的Dictionary接口,但有时需要按特定顺序获取数据,那么下面的方法会有所帮助。

将数据存储在常规Dictionary 中。要按排序顺序获取Dictionary 数据,您可以提供如下方法。

IOrderedEnumerable<KeyValuePair<string, List<int>>> GetSortedData() {
    return mySortedDictionary.OrderBy(item => item.Value.Count).ThenBy(item => item.Key);
}

【讨论】:

  • 非常感谢!!!我正是这个意思。现在我的应用程序可以正常工作了。
【解决方案2】:

我相信SortedDictionary 类型仅对key 部分(这是您的要求的一部分)进行排序,但您也可以使用OrderBy() 方法来指定自定义排序。请注意,这不会更改字典中元素的顺序,而是返回具有指定顺序的IOrderedEnumerable。因此,如果要更改顺序,则必须将字典重新分配给 OrderBy 调用的结果。如果这就是你想要做的,也许这会有所帮助:

var mySortedDictionary = new SortedDictionary<string, List<int>>
{
    {"orange", new List<int> {2, 9}},
    {"money", new List<int> {2, 4, 8, 9}},
    {"monkey", new List<int> {2, 4, 9}},
    {"hokey", new List<int> {2, 5, 9}}
};

foreach (var item in mySortedDictionary.OrderBy(item => item.Value.Count))
{
    Console.WriteLine($"{item.Key} {string.Join(", ", item.Value)}");
}

输出:

要在字典中保留此顺序,您必须重新分配,如下所示:

mySortedDictionary = mySortedDictionary.OrderBy(item => item.Value.Count);

【讨论】:

    【解决方案3】:

    您需要一个自定义类来实现IComparable,因此您希望使用SortedDictionary 进行排序。

    public class ncKey : IComparable {
        public int count;
        public string name;
    
        public int CompareTo(object other) {
            var b = other as ncKey;
            var ans1 = count.CompareTo(b?.count);
            return (ans1 == 0) ? name.CompareTo(b?.name) : ans1;
        }
    }
    

    现在您可以使用该类来获得正确排序的字典:

    var newSD = new SortedDictionary<ncKey, List<int>>();
    
    foreach (var kv in origSD)
        newSD.Add(new ncKey { count = kv.Value.Count(), name = kv.Key }, kv.Value);
    

    当然,我想知道您是否真的使用SortedList 会更好,以及您为什么要使用字典。

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-06
      相关资源
      最近更新 更多