javascript 根据word_number键高效地对字典(或js中任何键值数据结构)进行排序

p1iqtdky  于 2022-12-21  发布在  Java
关注(0)|答案(6)|浏览(193)

如何按键对字典进行排序

dict["word_21"] = "Hello Java";
dict["word_22"] = "Hello World";
dict["word_11"] = "Hello Javascript";

这样我就能

dict["word_22"] = "Hello World";
dict["word_21"] = "Hello Java";
dict["word_11"] = "Hello Javascript";

只有索引上有word_number组合,并且值是字符串。索引是不同的(没有相等的值),但在错误情况下可能是“未定义的
编辑:实际上我需要它的降序和升序。但降序是我目前需要的。

ctehm74n

ctehm74n1#

试试这个

var sorted = [];
for(var key in dict) {
    sorted[sorted.length] = key;
}
sorted.sort();

按键对dict进行排序并将其写回对象对我来说没有意义,但可以这样做:

function sortOnKeys(dict) {

    var sorted = [];
    for(var key in dict) {
        sorted[sorted.length] = key;
    }
    sorted.sort();

    var tempDict = {};
    for(var i = 0; i < sorted.length; i++) {
        tempDict[sorted[i]] = dict[sorted[i]];
    }

    return tempDict;
}

dict = sortOnKeys(dict);
neskvpey

neskvpey2#

一个javascript对象,这里用作键-值-Map(称为“字典”),没有顺序;也就是说,你不能把它分类。
您需要一个数组来完成此操作,例如。

[
    {id: "word_11", entry:"Hello Javascript"},
    {id: "word_21", entry:"Hello Java"},
    {id: "word_22", entry:"Hello World"},
]

然后你可以按id或者条目排序,你可以用your id-sort-algorithm
或者你可以使用一个键数组来排序,紧挨着未排序的数据结构,这可能是最好(有效)和最简单的方法:

var dict = {
    "word_21": "Hello Java",
    "word_22": "Hello World",
    "word_11": "Hello Javascript"
}; // init (like your example)

var keys = Object.keys(dict); // or loop over the object to get the array
// keys will be in any order
keys.sort(); // maybe use custom sort, to change direction use .reverse()
// keys now will be in wanted order

for (var i=0; i<keys.length; i++) { // now lets iterate in sort order
    var key = keys[i];
    var value = dict[key];
    /* do something with key & value here */
}
pod7payv

pod7payv3#

如果你只想对一个对象中的键进行排序,下面的代码就可以了(一行代码)

/**
 * (typescript) returns the given object with keys sorted alphanumerically.
 * @param {T} obj the object to sort
 * @returns {T} the sorted object
 */
 const sort = <T extends object>(obj: T): T => Object.keys(obj).sort()
        .reduce((acc, c) => { acc[c] = obj[c]; return acc }, {}) as T

或者在JavaScript中相同

/**
 * (javascript) returns the given object with keys sorted alphanumerically.
 * @param {T} obj the object to sort
 * @returns {T} the sorted object
 */
 const sort = (obj) => Object.keys(obj).sort()
        .reduce((acc, c) => { acc[c] = obj[c]; return acc }, {})
jfgube3f

jfgube3f4#

@Amberlamps很好的解决方案在大多数情况下都有效。但是,OP是正确的,某些键存在 * 拆分问题 *。javascript中sort()的默认行为是使用字符串Unicode码点来确定元素的顺序。例如,使用@Amberlamps方法,以下键 * 不会 * 得到正确的排序:

canvas_2_1/15/2018__2:55:20_PM

canvas_24_1/15/2018__2:55:20_PM

但是我们可以利用sort()接受一个 optional argument(可选参数)这一事实来定制sort方法,这个参数是一个比较数组中两个元素的函数
通过定制compare函数的排序逻辑并将其传递给sort()方法,上面的键可以正确排序:

sorted.sort(function(a, b) {
    a = parseInt(get_between(a, 'canvas_', '_'));
    b = parseInt(get_between(b, 'canvas_', '_'));
    if (a > b) {
        return 1;
    }
    if (b > a) {
        return -1;
    }
    return 0;
    });

在本例中,我使用下面的get_between方法:

function get_between(str, char_a, char_b) {
   res = str.split(char_a).pop().split(char_b).shift();
   return(res)
}

关键是,如果您有一些棘手的键(可能是也可能不是dict的“正确”用法),您可以调整sort函数,使其仍然能够正确排序。

ecr0jaav

ecr0jaav5#

简单地说,dictionary类型没有keys()方法,而Object类型有,你可以给Object.keys()方法传递一个可迭代对象,然后把键作为一个列表返回,这个列表有一个.sort()方法。

Object.keys({r:2,d:2,c:3,p:0})
// returns ["r", "d", "c", "p"]
Object.keys({r:2,d:2,c:3,p:0}).sort()
// returns ["c", "d", "p", "r"]
Object.keys([6,7,8,9])
// returns ["0", "1", "2", "3"]

最后,让我们用jsFiddle the OP's code
更新:Bergi的回答太复杂了,我完全错过了“好答案”的部分,我甚至没有注意到他做了我在jsFiddle中做的同样的事情。

nuypyhwy

nuypyhwy6#

要理解为什么不能对字典进行排序,我们首先需要了解字典是如何工作的。与根据索引对条目进行排序的列表不同,字典将条目存储在由其键的哈希值指示的位置。使用您的示例,值“Hello Java”被存储在“word_21”处。该过程涉及使用数学函数将“word_21”转换成可用作地址的数字。使用哈希表(字典的另一个名字)的好处是它在查找值时非常有效,因为对键进行哈希比搜索列表中的每个元素要容易得多。
总结一下,没有办法像你所要求的那样对字典进行重新排序。将一个值放在另一个值之前的唯一方法,也就是改变它的位置,是通过改变它的键。最好把顺序看作是任意的,不可预测的。
虽然字典对于快速访问基于键的值确实很有帮助,但您可能会考虑使用不同的数据类型来满足您的情况。当您可以更容易地使用列表索引时,为什么要使用编号键呢?如果您正在寻找一种快速访问基于键的动态变化值的方法,请使用dict。如果您希望快速访问基于索引的元素并进行排序,请使用列表。尽管如此,现在你可以在大多数语言中找到有序字典,它们也把键存储在有序列表中用于索引。2在JS中,我相信这仍然需要第三方库。

相关问题