将对象转换为数组的最快方法

时间:2014-02-21 13:53:36

标签: javascript

我已经看到很多方法可以将Javascript对象转换为数组。我正在使用的一件事是:

shims.values = function (obj) {
    var keys = Object.keys(obj);
    var length = keys.length;
    var values = new Array(length);
    for (var i = 0; i < length; i++) {
        values[i] = obj[keys[i]];
    }
    return values;
};

我知道没有像Object.keys(Object.values会很棒)。

现在,如果我有一个包含数千个值的对象,我想将其变成一个数组,那么上面的函数就会变慢。

E.g。 转过来:

{
    1: {a:"a"},
    1: {b:"b"},
    ....
    1000000: {c:"c"},
}

进入这个:

  [{a:"a"},{b:"b"},...,{c:"c"}]

有更好(更快)的方式吗?

4 个答案:

答案 0 :(得分:2)

Array.slice适用于类似数组的对象以及数组(如arguments):

Array.prototype.slice.call(obj, 0);

编辑:正如Jonathan Lonowski所说,该对象需要一个正确的length属性。如果对象中没有任何其他属性,则可以只计算键:

obj.length = Object.keys(obj).length;
Array.prototype.slice.call(obj, 0);

EDIT2:jsPerf显示这不比使用for循环慢得多。所以,不是最快,但绝对短,而不是半坏。 :)

答案 1 :(得分:1)

这是最短的&amp;使用纯旧js的最快方式。

并且它与所有浏览器兼容。

var a=[],b;
for(b in obj){
 a.push(obj[b]);
}

<强>样本

http://jsfiddle.net/B72Sa/

或者像@GJK中提到的更新的js版本

Array.prototype.slice.call

如果是一个连续的数值。

注意:它取决于对象的键...你不能对对象进行排序。

编辑 - 表现

http://jsperf.com/for-vs-array-proto

<强> EDIT2

由于@Christian正在使用hasOwnProperty,这是javascript的新版本的一部分,因此不再需要

Object.keys(obj) ...在这种情况下,可以定义原型而不必枚举。

示例:

Object.defineProperty(obj.prototype,'myProto',{value:function(){
 return this; 
},writable:false,enumerable:false});

<强> EDIT3

没有什么比普通的旧javascript更快。

Array.prototype.slice.call

意味着你执行切片而不是调用...所以2个函数......不要谈论call有多慢。

然后如果你也需要Object.keys(obj) ....你需要执行另一个函数......

又慢了......

所以...玩jsperf并测试它

答案 2 :(得分:0)

您似乎已将object.1声明两次,这会导致错误。

尝试使用常规foreach循环迭代对象并定义新数组。

var i = 0,
    new_array = [];

for (key in obj) {
    new_array[i] = obj[key];
    i++;
}

console.log(new_array);

答案 3 :(得分:0)

不确定这是否更快,但另一种(较小的)解决方案可能

function obj_to_array(obj){
    var result = [];
    for(var i in obj){ 
        var tmp = {}; 
        tmp[i] = obj[i]; 
        result.push(tmp); 
    }
    return result;
 }