如何将数组转换为对象?

826
什么是最好的转换方式:
['a','b','c']

到:

{
  0: 'a',
  1: 'b',
  2: 'c'
}

2
如果其他人正在寻找Lodash解决方案,请考虑使用_.keyBy(以前称为_.indexBy):https://lodash.com/docs#keyBy - 2540625
1
这有点令人困惑,因为数组已经是对象了,但我猜问题的重点是将数组 异类对象转换为普通对象 - Oriol
3
使用 Lodash 来简单实现这个操作的方法是 _.toPlainObject。例如:var myObj = _.toPlainObject(myArr) - julian soro
46个回答

18

顺便说一句,另一种较新的方法是使用新的Object.fromEntriesObject.entries组合如下:

const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));

...它可以避免将稀疏数组项存储为undefinednull,并保留非索引(例如,非正整数/非数值)键。

{ 0: "a", 1: "b", 2: "c", "-2": "d", hello: "e" }

(与@Paul Draper的Object.assign答案相同的结果.)

但是,你可能希望添加arr.length,因为它没有包括在内:

obj.length = arr.length;

你可以使用 arr.entries() 代替 Object.entries(arr) - Antoine Weber

15

可以使用javascript#forEach来完成这一操作。

var result = {},
    attributes = ['a', 'b','c'];

attributes.forEach(function(prop,index) {
  result[index] = prop;
});

使用ECMA6:

attributes.forEach((prop,index)=>result[index] = prop);

13

如果您的数组包含 由两个元素组成的数组,其中第一个元素是键,第二个元素是值,那么您可以使用 reduce 轻松地将其转换为对象。

[
  ["key1","value1"], 
  ["key2", "value2"], 
  ["key3", "value3"]
]
.reduce((acc, [key, value])=>({...acc, [key]: value}), {});

结果:

{  
  key1: 'value1',   
  key2: 'value2', 
  key3: 'value3'  
}  

10

如果你正在使用ES6,你可以使用Object.assign和展开运算符

{ ...['a', 'b', 'c'] }

如果您有像嵌套数组这样的结构:

var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))

1
你的变量名不仅不同,而且你的示例无法工作,从构造函数创建地图最初需要2D键值数组。new Map([['key1', 'value1'], ['key2', 'value2']]); - Shannon Hochkins

6
一个快速而简略的方法:
var obj = {},
  arr = ['a','b','c'],
  l = arr.length; 

while( l && (obj[--l] = arr.pop() ) ){};

1
我认为你忘记测试了,它会产生 {0:"c",1:"b",2:"a"}。你可能想使用 unshift,而不是 pop 或者(更好的方式)从 i=arr.length-1 开始,并递减。 - Phrogz
1
是的,我刚刚改了它,但后来它变得不那么有趣了 :/ - Mic
1
甚至可以这样做 l = arr.length,然后 while (l && (obj[--l] = arr.pop())){}(我知道这很老了,但为什么不进一步简化呢)。 - Qix - MONICA WAS MISTREATED
3
好的,我会尽力进行翻译。以下是需要翻译的内容:@Qix, Nice shortening - Mic
它是否比其他解决方案更快? - PEZO

6

简单粗暴 #2:

var i = 0
  , s = {}
  , a = ['A', 'B', 'C'];

while( i < a.length ) { s[i] = a[i++] };

你为什么要使用逗号表示法? - Conner Ruhl
3
个人偏好将逗号放在下一行开头。我发现这种标记更容易阅读。 - BingeBoy
2
如果数组包含一个假值,循环将停止。您应该检查 i < a.length 而不是 a[i] - Oriol

6

更多浏览器支持更加灵活的做法是使用普通的循环,示例如下:

const arr = ['a', 'b', 'c'],
obj = {};

for (let i=0; i<arr.length; i++) {
   obj[i] = arr[i];
}

不过现代的方法可能是使用展开运算符,例如:

{...arr}

或者使用Object.assign函数:
Object.assign({}, ['a', 'b', 'c']);

两者都会返回

{0: "a", 1: "b", 2: "c"}

5

为什么没有人在ES6中尝试这个?

let arr = ['a','b','c']
let {...obj} = arr
console.log(obj) //  {0: 'a', 1: 'b', 2: 'c'}

let {...obj2} = ['a','b','c']
console.log(obj2) //  {0: 'a', 1: 'b', 2: 'c'}

这是一种非常简单的方法吗?


10
与其仅仅批评其他回答没有尝试某些方法,你可以使用 "展开语法" 解释你的答案有何优势或与顶部答案有何不同。提示:请参阅 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#rest_property。 - General Grievance
如何将键变为值? - Yogi Arif Widodo

5
最简单的答案是:(使用解构)
const obj = { ...input }

例子:

const inputArray = ["a", "b", "c"]
const outputObj = { ...inputArray }

5
一个简单而巧妙的方法,可以快速将一个数组转换为对象。
function arrayToObject( srcArray ){
    return  JSON.parse( JSON.stringify( srcArray ) );
}

然后像这样使用它...
var p = [0,2,3,'pork','pie',6];
obj = new arrayToObject( p );
console.log( obj[3], obj[4] )
// expecting `pork pie`

输出:

pork pie

检查类型:

typeof obj
"object"

如果没有原型方法,事情就不完整了。

Array.prototype.toObject =function(){
    return  JSON.parse( JSON.stringify( this ) );
}

使用方式:

var q = [0,2,3,'cheese','whizz',6];
obj = q.toObject();
console.log( obj[3], obj[4] )
// expecting `cheese whizz`

输出:

cheese whizz

*注意:没有命名例程,如果您想要具体的名称,则需要继续使用下面的现有方法。


旧方法

这允许您从数组中生成一个对象,其中包含您按照所需顺序定义的键。

Array.prototype.toObject = function(keys){
    var obj = {};
    var tmp = this; // we want the original array intact.
    if(keys.length == this.length){
        var c = this.length-1;
        while( c>=0 ){
            obj[ keys[ c ] ] = tmp[c];
            c--;
        }
    }
    return obj;
};

result = ["cheese","paint",14,8].toObject([0,"onion",4,99]);

console.log(">>> :" + result.onion);将输出"paint",该函数需要具有相等长度的数组,否则将得到一个空对象。

这是更新后的方法。

Array.prototype.toObject = function(keys){
    var obj = {};
    if( keys.length == this.length)
        while( keys.length )
            obj[ keys.pop() ] = this[ keys.length ];
    return obj;
};

这将销毁keys数组内容,并且尽管有内部注释,也会破坏values数组(其内容)。JavaScript与PHP的工作方式不同,JavaScript自动通过引用处理对象/数组的属性。 - Brett Zamir
不会的,这个程序会创建副本,原始数据不会被修改。 - Mark Giblin
是的,原始数据被修改了。请参见http://jsfiddle.net/bRTv7/。数组长度最终都为0。 - Brett Zamir
好的,我刚刚更改的编辑版本没有破坏数组,发现这应该不正常。 - Mark Giblin
1
更新的方法应该在旧浏览器中得到支持,因为JSON已经存在比ECMA添加新代码功能更长的时间。 - Mark Giblin
显示剩余2条评论

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