按值对Javascript对象进行排序

4
在我的Javascript应用程序中,我有一个对象,并且我需要能够按照内部对象中的值对数组进行排序。
例如:
{
    a : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    b : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    c : {
        timestamp: xxxxxx
        other : yyyyyy
    }
}

我需要做的是管理这个数据集,并根据每个内部对象的时间戳重新排序数组。
有什么方法可以实现?
更新:
我最初的想法是这样做:
{
    a : {},
    b : {},
    c : {},
    _ : [
        c, a, b //Key's Only
    ]
}

然后根据这些值重新索引对象,这将解决如何索引对象的问题,但是当我插入新元素时,还必须重新生成_索引关系,这似乎需要太多的工作。

5个回答

6
你可以将数据复制到一个数组中,然后对其进行排序:
var data = {
    a : {
        timestamp: 11111,
        other : "xxx"
    },
    b : {
        timestamp: 22222,
        other : "yyy"
    },
    c : {
        timestamp: 33333,
        other : "zzz"
    }
};

var output = [];

// copy items to an array so they can be sorted
for (var key in data) {
    data[key].key = key;   // save key so you can access it from the array (will modify original data)
    output.push(data[key]);
}    

output.sort(function(a,b) {
    return(a.timestamp - b.timestamp);
});

生成如下输出(请注意我已将原始键添加到对象中,因此可以从数组中访问):
[{"timestamp":11111,"other":"xxx","key":"a"},
{"timestamp":22222,"other":"yyy","key":"b"},
{"timestamp":33333,"other":"zzz","key":"c"}]

您可以在这里查看它的工作原理:http://jsfiddle.net/jfriend00/hXpkP/

不要忘记在测试对象属性时加上 hasOwnProperty,否则可能会包含继承的属性。 - RobG

2

你处理的不是一个数组,而是一个具有属性值 abc 的对象。

没有理由需要按特定顺序使用它们,因为你无法按任何特定顺序循环遍历它们。

如果你正在使用数组,这将是微不足道的(使用 sort 可以解决问题)...

var array = [
    {
        timestamp: xxxxxx
        other : yyyyyy
    },
    {
        timestamp: xxxxxx
        other : yyyyyy
    },
    {
        timestamp: xxxxxx
        other : yyyyyy
    }
];

array.sort(function(a,b) {
    return a.timestamp - b.timestamp;
});

数组的问题在于它们没有基于字符串的索引,而要快速访问需要基于字符串的索引。 - RobertPitt
所有的 JavaScript 索引都是字符串,JavaScript 数组则是对象,它们只是有一些额外的有用特性... 其中一个你特别需要的... http://jsfiddle.net/Mb8xC/ - jondavidjohn

2

正如其他人已经说过的,你正在处理一个关联对象,而不是数组。对象没有顺序。

如果您希望保持原样,并对键的数组进行排序,则可以执行以下操作:

var obj = {
    a : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    b : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    c : {
        timestamp: xxxxxx
        other : yyyyyy
    }
};

var keys = [];
for(var key in obj) {
    keys.push(key);
}

keys.sort(function(a, b) {
    return obj[a].timestamp - obj[b].timestamp;
});

现在,您可以通过数组值访问对象(例如 obj[keys[0]]、obj[keys[1]] 等)。这假设时间戳是数字类型。如果它们是日期对象,则排序应该如下:

keys.sort(function(a, b) {
    return +obj[a].timestamp - (+obj[b].timestamp);
});

如果时间戳实际上是表示日期时间的字符串(例如“2012年8月2日”),则应该是这样的:
keys.sort(function(a, b) {
    return +new Date(obj[a].timestamp) - (+new Date(obj[b].timestamp));
});

因此,请根据您的情况使用最合适的方法。


2
Javascript对象不是关联数组。它们可能行为类似,但它们不同。Javascript没有关联数组。
虽然关联数组有一个顺序的概念,但Javascript对象根本就没有与之共享这个特定的功能。对象本质上是无序的。
因此,回答你的问题:你不能对它们排序...

1
当然,对象没有顺序,但这并不意味着不存在可能的解决方案。 - jondavidjohn
你可以创建一个键值和“顺序”的索引、哈希表,并在需要时使用一个数组中的引用来访问对象。 - Miguel

0
你可以创建一个自定义比较函数并使用内置的数组排序函数。请参考这篇帖子

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接