在Javascript中按值排序哈希/数组

Sorting a Hash/Array by value in Javascript

本文关键字:哈希 数组 排序 Javascript      更新时间:2023-09-26

我用下面的代码来生成一个简单的哈希数组。

function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}
var arr = [];
for (i=0; i<10; i++) {
    var id = 'user-' + Math.floor(getRandomArbitrary(0,1000));
    var xp = Math.floor(getRandomArbitrary(2000,3000));
    arr[id] = ({'xp':xp});
}

现在循环遍历数组:

for (id in arr) {
    document.write(id + ': ' + arr[id].xp + '<br>');
}

一个示例结果是:

user-750: 2085
user-681: 2051
user-790: 2174
user-542: 2537
user-943: 2913
user-678: 2829
user-365: 2398
user-886: 2571
user-635: 2525
user-786: 2482

这将显示所有用户和他们的XP。

问题是,我如何按XP(降序)排序这个数组?

开头:

arr = arr.sort(function(a,b) {
    return b.xp - a.xp;
});

无法排序,因为您没有将该数组作为数组使用。

数组也是一个对象,这就是为什么您可以使用键(如"user-750")向其添加项。这些项是数组对象中的属性,它们不是数组中的项。当你对数组进行排序时,它只会对项目进行排序,数组中没有项目,所以排序不会改变任何东西。

不能对属性进行排序,因为属性的顺序未定义。如果您尝试以特定的顺序添加属性,则它们仍将按照内部存储方式的顺序返回。这是特定于实现的,不同的浏览器实际上会以不同的顺序返回属性。

如果要对数组进行排序,则必须将对象添加为数组中的项,而不是属性:

arr.push({ id: id, xp: xp });

你的'array'不是一个数组,而是一个对象:

{ 
  'user-750': {xp: 2085}
  'user-681': {xp: 2051}
  ...
}

如果你想排序,你需要一个对象数组:

[
 {id: 'user-750', xp: 2085},
 {id: 'user-681', xp: 2051},
  ...
]

对象数组应该是可排序的。

这是我用来排序的一个自制排序器方法(在这个jsFiddle中演示):

function sorter(sortOn,descending) {
    sortOn = sortOn && sortOn.constructor === Object ? sortOn : {};
    return function ( a, b ) {
        if (sortOn.string || sortOn.numeric || sortOn.key) {
            a = sortOn.key ? a[sortOn.key] : a;
            a = sortOn.string ? String(a) : sortOn.numeric ? +a : a;
            b = sortOn.key ? b[sortOn.key] : b;
            b = sortOn.string ? String(b) : sortOn.numeric ? +b : b;
            if (sortOn.key && (!b || !a)) { //empty values on top
                return !a && !b ? 1 : !a ? 1 : -1;
            }
        }
        return descending 
                ? (a < b ? 1 : a > b ? -1 : 0)
                : (a < b ? -1 : a > b ? 1 : 0);
    };
}
// usage
arr = arr.sort( sorter({key: 'xp', numeric: 1}, true) );

我认为你必须设定你的优先级。

1)如果你想排序你的记录,你可以使用数组。但是要查找特定的键,必须遍历key.

2)如果你想按键获取记录,你可以使用object/hash,但是你不能对记录进行排序,哈希没有特定的顺序。

如果你要使用数组&排序,我认为你应该改变一下你的实现当你在数组中推东西。

像风箱

arr.push({ id: id, xp: xp });