【问题标题】:Sort a dictionary by value in JavaScript在 JavaScript 中按值对字典进行排序
【发布时间】:2014-10-19 10:53:39
【问题描述】:

这是我的字典:

const dict = {
  "x" : 1,
  "y" : 6,
  "z" : 9,
  "a" : 5,
  "b" : 7,
  "c" : 11,
  "d" : 17,
  "t" : 3
};

我需要一种方法来将我的dict 字典从最小到最大或从最大到最小排序。或者即使我有一个带有排序键的数组也可以。但我不知道如何使用javascript 来做这样的事情。我在使用python之前已经做到了,像这样:

import heapq
from operator import itemgetter

thirty_largest = heapq.nlargest(8, dict.iteritems(), key=itemgetter(1))

我在 Google 中搜索过,发现数组有 sort() 函数但没有字典。所以我的问题是:如何对字典进行排序按排序顺序获得前 5 个最大值?

【问题讨论】:

  • 在 JS 中,你有对象(不是字典)。关于这个主题有一些关于 SO 的问题......你可以看看例如:Sorting JavaScript Object by property value.
  • 它似乎是按价值计算的,见最后一行:get top 5 maximum values...
  • 由于javascript中的对象(字典)没有顺序,排序这样的东西没有意义。因此,我强烈建议您将标题更改为“我如何获得前 5 个最大值”以避免人们关闭此问题。
  • 他说他想按字典的键对字典进行排序。 JS 中不存在字典,因此我们可以构建一个键/值有序结构来满足他的需求,它看起来像一个“字典”。没必要改变他的问题。我认为这是来自其他语言的人的常见问题,所以我认为这个标题应该保持原样
  • Object.keys(dict).sort() 返回一个键排序的数组。然后,您可以在需要时使用它来遍历字典。

标签: javascript sorting object dictionary


【解决方案1】:

在 JavaScript 中可能不是直截了当的。

var dict = {
  "x": 1,
  "y": 6,
  "z": 9,
  "a": 5,
  "b": 7,
  "c": 11,
  "d": 17,
  "t": 3
};

// Create items array
var items = Object.keys(dict).map(function(key) {
  return [key, dict[key]];
});

// Sort the array based on the second element
items.sort(function(first, second) {
  return second[1] - first[1];
});

// Create a new array with only the first 5 items
console.log(items.slice(0, 5));

第一步,创建items数组,类似Python的

items = map(lambda x: [x, var[x]], var.keys())

可以方便地写成

items = list(dict.items())

并且排序步骤类似于Python的带有cmp参数的排序

items.sort(cmp=lambda x, y: y[1] - x[1])

最后一步类似于Python的切片操作。

print items[:5]
// [['d', 17], ['c', 11], ['z', 9], ['b', 7], ['y', 6]]

【讨论】:

    【解决方案2】:

    @thefourtheye 提供的答案在一定程度上有效,但它不会返回相同的“字典”结构。

    如果你想返回一个与你开始时结构相同的排序对象,你可以在从接受的答案返回的项目上运行这个:

    sorted_obj={}
    $.each(items, function(k, v) {
        use_key = v[0]
        use_value = v[1]
        sorted_obj[use_key] = use_value
    })
    

    将它们组合成一个对 JavaScript 对象进行排序的函数

    function sort_object(obj) {
        items = Object.keys(obj).map(function(key) {
            return [key, obj[key]];
        });
        items.sort(function(first, second) {
            return second[1] - first[1];
        });
        sorted_obj={}
        $.each(items, function(k, v) {
            use_key = v[0]
            use_value = v[1]
            sorted_obj[use_key] = use_value
        })
        return(sorted_obj)
    } 
    

    示例

    只需将您的对象传递给 sort_object 函数

    dict = {
      "x" : 1,
      "y" : 6,
      "z" : 9,
      "a" : 5,
      "b" : 7,
      "c" : 11,
      "d" : 17,
      "t" : 3
    };
    
    sort_object(dict)
    

    结果

    {
    "d":17,
    "c":11,
    "z":9,
    "b":7,
    "y":6,
    "a":5,
    "t":3,
    "x":1
    }
    

    “证明”

    res = sort_object(dict)
    
    $.each(res, function(elem, index) {
        alert(elem)
    })
    

    【讨论】:

    • 但是...不是循环遍历字典,根据定义,是无序的吗?我的意思是,如果我打印出那本字典,它将是随机顺序的
    • @johnktejik 看到答案中的“证明”......它将以新订单重复循环。从技术上讲,您是正确的,在 JavaScript 中的“字典”类型对象中不应该信任 order,但是如果您在调用 sort_object 后立即使用新排序的对象,则可以使用它。所以从技术上讲,Rayjax 是正确的,使用对象数组,因为这样可以保证顺序,但是正如我所展示的那样,可能有一些用例可以让你快速订购你的对象。
    • 干得好,顺便说一句,使用items.forEach( function(v) { ... }) 代替$.each(items, function(k, v) { ... }) 以更好地兼容不同版本的JS 引擎
    【解决方案3】:

    你可以试试下面的代码。它按值排序整数数组。

    jsFiddle link

     function sortJsObject() {
        var dict = {"x" : 1, "y" : 6,  "z" : 9, "a" : 5, "b" : 7, "c" : 11, "d" : 17, "t" : 3};
    
        var keys = [];
        for(var key in dict) { 
           keys[keys.length] = key;
         }
    
         var values = [];     
         for(var i = 0; i < keys.length; i++) {
             values[values.length] = dict[keys [i]];
         }
    
         var sortedValues = values.sort(sortNumber);
         console.log(sortedValues);
    }
    
    // this is needed to sort values as integers
    function sortNumber(a,b) {
       return a - b;
    }
    

    希望对你有帮助。

    【讨论】:

    • 如何用这个排序值取回字典?
    • @SaurabhSashank 只是返回它?喜欢return sortedValues
    【解决方案4】:

    首先,你可能称之为“字典”的东西在 JavaScript 中称为“对象”。你的 'dict' 变量是一个对象。

    在 JS 中对象没有排序,所以你不能对对象进行排序。幸运的是数组是有序的;我们会将您的字典转换为数组。看看下面吧。

    //dict -> a js object
    var dict = {"x" : 1,
            "y" : 6,
            "z" : 9,
            "a" : 5,
            "b" : 7,
            "c" : 11,
            "d" : 17,
            "t" : 3};
    
    //Use the 'keys' function from the Object class to get the keys of your dictionary
    //'keys' will be an array containing ["x", "y", "z"...]
    var keys = Object.keys(dict);
    
    //Get the number of keys - easy using the array 'length' property
    var i, len = keys.length; 
    
    //Sort the keys. We can use the sort() method because 'keys' is an array
    keys.sort(); 
    
    //This array will hold your key/value pairs in an ordered way
    //it will be an array of objects
    var sortedDict = [];
    
    //Now let's go throught your keys in the sorted order
    for (i = 0; i < len; i++)
    {
        //get the current key
        k = keys[i];
    
        //show you the key and the value (retrieved by accessing dict with current key)
        alert(k + ':' + dict[k]);
    
        //Using the array 'push' method, we add an object at the end of the result array
        //It will hold the key/value pair
        sortedDict.push({'key': k, 'value':dict[k]});
    }
    
    //Result
    console.log(sortedDict);
    

    你可以试试 here

    如果你想改变排序,看看here

    如果你想要前五个最大值,那么,用 for 循环遍历 sortedDict 5 次并取出这些值:

    function getFiveFirstValues(){
        var valuesArray = [];
        for (i = 0; i < 5; i++)
        {
            valuesArray.push(sortedDict[i].value);
        }
        return valuesArray;
    }
    

    请记住,在 JavaScript 中,对象是无序的。 它们可能看起来是有序的,但实际上并非如此,并且根据浏览器的 JS 实现,它们的顺序可能会有所不同。

    在本例中,sortedDict 是一个数组(已排序),因此可以排序。 在该数组的每个元素中,您会为每对“字典”找到一个 KEY 和 VALUE 对。

    【讨论】:

      【解决方案5】:

      严格来说,您不能对“字典”(JavaScript 对象)进行排序,因为 JavaScript 对象没有顺序。它们只是键/值对的“包”。

      如果你想找到对象中的n个最大值,那么你需要将对象转换成一个数组,其元素有序的,例如@thefourtheye的解决方案。如果您想对键进行排序,那么可以使用Object.keys(object).sort() 对它们进行排序,因为另一个答案会告诉您如何操作。

      【讨论】:

        【解决方案6】:

        这是一段完整的代码,根据之前的回答和How to iterate (keys, values) in JavaScript?

        class DictUtils {
            static entries(dictionary) {
        
                try {
        
                    //ECMAScript 2017 and higher, better performance if support
                    return Object.entries(dictionary);
        
                } catch (error) {
        
                    //ECMAScript 5 and higher, full compatible but lower performance
                    return Object.keys(dictionary).map(function(key) {
                        return [key, dictionary[key]];
                    });
                }
        
            }
            
            static sort(dictionary, sort_function) {
                return DictUtils.entries(dictionary)
                    .sort(sort_function)
                    .reduce((sorted, kv)=>{
                        sorted[kv[0]] = kv[1]; 
                        return sorted;
                    }, {});
            }
        
        } 
        
        class SortFunctions {
            static compare(o0, o1) {
                //TODO compelte for not-number values
                return o0 - o1;
            }
            static byValueDescending(kv0, kv1) {
                return SortFunctions.compare(kv1[1], kv0[1]);
            }
            static byValueAscending(kv0, kv1) {
                return SortFunctions.compare(kv0[1], kv1[1]);
            }
        
        }
        
        let dict = {
            "jack": 10,
            "joe": 20,
            "nick": 8,
            "sare": 12
        }
        
        let sorted = DictUtils.sort(dict, SortFunctions.byValueDescending)
        
        console.log(sorted);

        【讨论】:

          猜你喜欢
          • 2011-02-09
          • 1970-01-01
          • 1970-01-01
          • 2014-07-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多