按值对 Javascript 对象进行排序

Sorting a Javascript object by value

提问人:RobertPitt 提问时间:9/14/2011 最后编辑:jondavidjohnRobertPitt 更新时间:9/16/2011 访问量:7170

问:

在我的 Javascript 应用程序中,我有一个 Object,我需要能够按 Inner Object 中的值对数组进行排序。

例如:

{
    a : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    b : {
        timestamp: xxxxxx
        other : yyyyyy
    },
    c : {
        timestamp: xxxxxx
        other : yyyyyy
    }
}

我需要做的是管理这个数据集,并根据每个内部对象的时间戳对数组重新排序。

我能做些什么来做到这一点?

更新:

我最初的想法是做这样的事情:

{
    a : {},
    b : {},
    c : {},
    _ : [
        c, a, b //Key's Only
    ]
}

然后根据这些值重新索引对象,这将解决如何索引对象,但是当我插入一个新元素时,我还必须重新生成索引关系,这似乎需要付出很多努力。_

JavaScript 数组 排序 字典 对象文字

评论


答:

2赞 Joseph Silber 9/14/2011 #1

Javascript 对象不是关联数组。它们的行为可能相似,但并不相同。Javascript 没有关联数组。

虽然关联数组具有顺序概念,但 Javascript 对象根本不与它们共享此特定功能。从本质上讲,对象是没有秩序的。

所以,要回答你的问题:你不能订购它们......

评论

1赞 jondavidjohn 9/14/2011
当然,对象没有顺序,但这并不意味着没有可能的解决方案。
0赞 Miguel 2/13/2017
您可以创建一个索引、键值和“顺序”的哈希表,并在需要时使用从一个数组到对象的引用
2赞 jondavidjohn 9/14/2011 #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;
});

评论

0赞 RobertPitt 9/14/2011
数组的问题在于它们没有基于字符串的索引,并且可以快速访问需要基于字符串的索引的元素。
0赞 jondavidjohn 9/14/2011
所有的 JavaScript 索引都是字符串,javascript 数组对象,它们只是有一些额外的有用功能......你特别追求的......jsfiddle.net/Mb8xC
2赞 Marshall 9/14/2011 #3

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

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

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;
});

现在,您可以通过数组值(e.g. 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));
});

因此,请使用方案中最有意义的任何内容。

0赞 Annie Lagang 9/14/2011 #4

您可以创建自定义比较器函数,并将内置的排序函数用于数组。看这个帖子

6赞 jfriend00 9/14/2011 #5

您可以将数据复制到数组中,然后对其进行排序:

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/

评论

0赞 RobG 9/14/2011
不要忘记对对象属性进行 hasOwnProperty 测试,或者可以包含继承属性。