在 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 中按值对字典进行排序的主要内容,如果未能解决你的问题,请参考以下文章