在 JavaScript 中按值对字典进行排序

Posted

技术标签:

【中文标题】在 JavaScript 中按值对字典进行排序【英文标题】:Sort a dictionary by value in 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() 返回一个键排序的数组。然后,您可以在需要时使用它来遍历字典。 【参考方案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);

【讨论】:

以上是关于在 JavaScript 中按值对字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中按值对地图进行排序?

在python中按值对defaultdict进行排序

如何在PHP中按值对对象数组进行排序

如何在reactjs / javascript中按值对对象数组进行分组

按值对字典进行排序[重复]

如何按值对 Python 字典进行排序? [复制]