转换的最佳方法是什么:
['a','b','c']
至:
{
0: 'a',
1: 'b',
2: 'c'
}
_.toPlainObject
。例如:var myObj = _.toPlainObject(myArr)
ECMAScript 6 引入了易于填充的 Object.assign
:
Object.assign() 方法用于将所有可枚举自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
数组自己的 length
属性不会被复制,因为它不可枚举。
此外,您可以在对象上使用 ES8 spread syntax 来实现相同的结果:
{ ...['a', 'b', 'c'] }
对于自定义键,您可以使用 reduce:
['a', 'b', 'c'].reduce((a, v) => ({ ...a, [v]: v}), {})
// { a: "a", b: "b", c: "c" }
使用这样的功能:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
您的数组或多或少只是一个对象,但数组确实有一些“有趣”和关于整数命名属性的特殊行为。以上将为您提供一个简单的对象。
编辑哦,您可能还想考虑数组中的“孔”:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) rv[i] = arr[i];
return rv;
}
在现代 JavaScript 运行时中,您可以使用 .reduce()
方法:
var obj = arr.reduce(function(acc, cur, i) {
acc[i] = cur;
return acc;
}, {});
这也避免了数组中的“漏洞”,因为这就是 .reduce()
的工作方式。
[]
) 确实没有意义。
const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
的更简洁方法
const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
arr.reduce((obj, cur, i) => (obj[i]=cur,obj), {});
呢?
您可以使用累加器,即 reduce
。
['a','b','c'].reduce(function(result, item, index, array) {
result[index] = item; //a, b, c
return result;
}, {}) //watch out the empty {}, which is passed as "result"
传入一个空对象 {}
作为起点;然后逐渐“增加”该对象。在迭代结束时,result
将是 {"0": "a", "1": "b", "2": "c"}
如果您的数组是一组键值对对象:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item) {
var key = Object.keys(item)[0]; //first property: a, b, c
result[key] = item[key];
return result;
}, {});
将产生:{a: 1, b: 2, c: 3}
为了完整起见,reduceRight
允许您以相反的顺序迭代您的数组:
[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)
将产生:{c:3, b:2, a:1}
您的蓄能器可以是任何类型的,以满足您的特定目的。例如,为了交换数组中对象的键和值,请传递 []
:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
var key = Object.keys(item)[0]; //first property: a, b, c
var value = item[key];
var obj = {};
obj[value] = key;
result.push(obj);
return result;
}, []); //an empty array
将产生:[{1: "a"}, {2: "b"}, {3: "c"}]
与 map
不同,reduce
不能用作 1-1 映射。您可以完全控制要包含或排除的项目。因此 reduce
允许您实现 filter
的功能,这使得 reduce
非常通用:
[{ a: 1},{ b: 2},{ c: 3}].reduce(function(result, item, index) {
if(index !== 0) { //skip the first item
result.push(item);
}
return result;
}, []); //an empty array
将产生:[{2: "b"}, {3: "c"}]
注意:reduce
和 Object.key
是 ECMA 5th edition
的一部分;你应该为不支持它们的浏览器(特别是 IE8)提供一个 polyfill。
查看 Mozilla 的默认实现。
如果您使用的是 jquery:
$.extend({}, ['a', 'b', 'c']);
{0: 'a', 1: 'b', 2: 'c'}
,这是预期的结果。
为了完整起见,ECMAScript 2015(ES6) 传播。将需要转译器(Babel)或至少运行 ES6 的环境。
console.log( { ...['a', 'b', 'c'] } )
我可能会这样写(因为我很少手头没有 underscorejs 库):
var _ = require('underscore');
var a = [ 'a', 'b', 'c' ];
var obj = _.extend({}, a);
console.log(obj);
// prints { '0': 'a', '1': 'b', '2': 'c' }
obj=_.extend({},a);
就可以完成这项工作。此外,如果您要遍历数组,我会说 _.each
比 _.map
更合适。总而言之,这在几个层面上都不是一个好的答案。
如果您想使用迭代对象的属性之一作为键,例如:
// from:
const arr = [
{
sid: 123,
name: 'aaa'
},
{
sid: 456,
name: 'bbb'
},
{
sid: 789,
name: 'ccc'
}
];
// to:
{
'123': { sid: 123, name: 'aaa' },
'456': { sid: 456, name: 'bbb' },
'789': { sid: 789, name: 'ccc' }
}
利用:
const result = arr.reduce((obj, cur) => ({...obj, [cur.sid]: cur}), {})
我们可以使用 Object.assign
和 array.reduce
函数将 Array 转换为 Object。
var arr = [{a:{b:1}},{c:{d:2}}] var newObj = arr.reduce((a, b) => Object.assign(a, b), {})控制台日志(新对象)
arr = [{ b: 1, d: 2 }]
转换为 obj。
这是一个 O(1) ES2015 方法,只是为了完整性。
var arr = [1, 2, 3, 4, 5]; // array, already an object
Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object
length
属性。 (3) 对象仍然是一个数组,Array.isArray(arr) === true
。 (4) 不删除特殊数组行为,例如 arr.length = 0
删除所有索引。 (5) Therefore, I think Object.assign
is much better。
Array.isArray
在这里为“对象”返回 true
,即使 instanceof Array
没有...
FWIW,另一种最近的方法是将新的 Object.fromEntries
与 Object.entries
一起使用,如下所示:
const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));
...这允许避免将稀疏数组项存储为 undefined
或 null
并保留非索引(例如,非正整数/非数字)键。
0:“a”,1:“b”,2:“c”,“-2”:“d”,你好:“e”}
(这里的结果与@Paul Draper 的 Object.assign
答案相同。)
但是,可能希望添加 arr.length
,因为它不包括在内:
obj.length = arr.length;
arr.entries()
而不是 Object.entries(arr)
使用 javascript#forEach
可以做到这一点
var result = {},
attributes = ['a', 'b','c'];
attributes.forEach(function(prop,index) {
result[index] = prop;
});
使用 ECMA6:
attributes.forEach((prop,index)=>result[index] = prop);
如果您使用的是 ES6,则可以使用 Object.assign 和扩展运算符
{ ...['a', 'b', 'c'] }
如果您有嵌套数组,例如
var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
new Map([['key1', 'value1'], ['key2', 'value2']]);
一个快速而肮脏的:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
{0:"c", 1:"b", 2:"a"}
。您要么想要 unshift
而不是 pop
,要么(更好)以 i=arr.length-1
开头并递减。
l = arr.length
,然后再做while (l && (obj[--l] = arr.pop())){}
(我知道这很旧,但为什么不进一步简化它)。
又快又脏#2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( i < a.length ) { s[i] = a[i++] };
i < a.length
而不是 a[i]
。
更多的浏览器支持和更灵活的方式是使用普通循环,例如:
const arr = ['a', 'b', 'c'],
obj = {};
for (let i=0; i<arr.length; i++) {
obj[i] = arr[i];
}
但现代方式也可以使用扩展运算符,例如:
{...arr}
或对象分配:
Object.assign({}, ['a', 'b', 'c']);
两者都将返回:
{0: "a", 1: "b", 2: "c"}
一种快速将项目数组转换为对象的简单而厚颜无耻的方法
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;
};
.reduce((o,v,i)=>(o[i]=v,o), {})
[文档]
或更详细
var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}
或者
var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})
最短的带有香草 JS 的
JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
=> "{"0":["a","X"],"1":["b","Y"]}"
一些更复杂的例子
[["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
=> Object {a: "X", b: "Y"}
更短(通过使用 function(e) {console.log(e); return e;}
=== (e)=>(console.log(e),e)
)
nodejs
> [[1, 2, 3], [3,4,5]].reduce((o,v,i)=>(o[v[0]]=v.slice(1),o), {})
{ '1': [ 2, 3 ], '3': [ 4, 5 ] }
[/文档]
[/docs]
有何打算?使代码片段可执行会更有用。
如果可以使用 Map
或 Object.assign
,那就很简单了。
创建一个数组:
const languages = ['css', 'javascript', 'php', 'html'];
下面创建一个以索引为键的对象:
Object.assign({}, languages)
使用地图复制与上述相同的内容
转换为基于索引的对象 {0 : 'css'}
等...
const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript
转换为基于值的对象 {css : 'css is great'}
等...
const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great
如果有人在寻找 Typescript 方法,我写了这个:
const arrayToObject = <T extends Record<K, any>, K extends keyof any>(
array: T[] = [],
getKey: (item: T) => K,
) =>
array.reduce((obj, cur) => {
const key = getKey(cur)
return ({...obj, [key]: cur})
}, {} as Record<K, T>)
它会:
强制第一个参数是对象数组帮助选择键强制键是所有数组项的键
例子:
// from:
const array = [
{ sid: 123, name: 'aaa', extra: 1 },
{ sid: 456, name: 'bbb' },
{ sid: 789, name: 'ccc' }
];
// to:
{
'123': { sid: 123, name: 'aaa' },
'456': { sid: 456, name: 'bbb' },
'789': { sid: 789, name: 'ccc' }
}
用法:
const obj = arrayToObject(array, item => item.sid) // ok
const obj = arrayToObject(array, item => item.extra) // error
${val}
; }, '') }) }, {} as Record这是我刚刚写的一个递归函数。它很简单而且效果很好。
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
}
这是一个示例 (jsFiddle):
var array = new Array();
array.a = 123;
array.b = 234;
array.c = 345;
var array2 = new Array();
array2.a = 321;
array2.b = 432;
array2.c = 543;
var array3 = new Array();
array3.a = 132;
array3.b = 243;
array3.c = 354;
var array4 = new Array();
array4.a = 312;
array4.b = 423;
array4.c = 534;
var array5 = new Array();
array5.a = 112;
array5.b = 223;
array5.c = 334;
array.d = array2;
array4.d = array5;
array3.d = array4;
array.e = array3;
console.log(array);
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
}
console.log(convArrToObj(array));
https://i.stack.imgur.com/KZHoT.png
['a' = '1', 'b' = '2', 'c' = '3']
并希望它像 {a: 1, b: 2, c: 3}
一样完美。
我只需使用 Array.of()
即可。 Array of has the ability to use it's context as a constructor.
注 2 of 函数是一种有意的通用工厂方法;它不要求它的 this 值是 Array 构造函数。因此,它可以转移到其他构造函数或被其他构造函数继承,这些构造函数可以使用单个数字参数调用。
所以我们可以将 Array.of()
绑定到一个函数并生成一个类似对象的数组。
函数虚拟(){}; var thingy = Array.of.apply(dummy,[1,2,3,4]); console.log(thingy);
通过利用 Array.of()
one can even do array sub-classing。
让我 = 0;让 myArray = [“第一”,“第二”,“第三”,“第四”]; const arrayToObject = (arr) => Object.assign({}, ...arr.map(item => ({[i++]: item}))); console.log(arrayToObject(myArray));
或使用
myArray = ["first", "second", "third", "fourth"] console.log({...myArray})
ES5 - 解决方案:
使用数组原型函数“push”和“apply”,您可以使用数组元素填充对象。
var arr = ['a','b','c']; var obj = 新对象(); Array.prototype.push.apply(obj, arr);控制台.log(obj); // { '0': 'a', '1': 'b', '2': 'c', length: 3 } console.log(obj[2]); // C
{ name: a, div :b, salary:c}
怎么办
尝试使用反射从数组项复制到对象。
var arr =['aa:23','bb:44','cc:55']
var obj ={}
arr.forEach(e => {
var ee = e.split(':')
Reflect.set(obj,ee[0],ee[1])
});
console.log(obj) // { aa: '23', bb: '44', cc: '55' }
你可以使用这样的函数:
var toObject = function(array) {
var o = {};
for (var property in array) {
if (String(property >>> 0) == property && property >>> 0 != 0xffffffff) {
o[i] = array[i];
}
}
return o;
};
这个应该更有效地处理稀疏数组。
它不是直接相关的,但我来这里是为了寻找一个用于合并嵌套对象的衬垫,例如
const nodes = {
node1: {
interfaces: {if1: {}, if2: {}}
},
node2: {
interfaces: {if3: {}, if4: {}}
},
node3: {
interfaces: {if5: {}, if6: {}}
},
}
解决方案是结合使用 reduce 和 object spread:
const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {})
Object.fromEntries(Object.entries(nodes).map(([key, value] => [key, value.interfaces]))
最简单的方法如下:
const arr = ['a','b','c'];
let obj = {}
function ConvertArr(arr) {
if (typeof(arr) === 'array') {
Object.assign(obj, arr);
}
这样它只有在它是一个数组时才运行,但是,你可以使用 let 全局对象变量或不使用它来运行它,这取决于你,如果你不使用 let 运行,只需执行 Object.assign({}, arr)。
这是咖啡脚本中的解决方案
arrayToObj = (arr) ->
obj = {}
for v,i in arr
obj[i] = v if v?
obj
obj[i] = v for v,i in arr when v?
不定期副业成功案例分享
{ ...[sortedArray]}
reduce
喜欢:arr.reduce((a, v) => ({ ...a, [v]: v}), {})