Преобразование массива в объект
каков наилучший способ преобразования:
['a','b','c']
в:
{
0: 'a',
1: 'b',
2: 'c'
}
30 ответов
ECMAScript 6 вводит легко polyfillable Object.assign
:
на
Object.assign()
метод используется для копирования значений всех перечисляемые собственные свойства от одного или нескольких объектов-источников до цели объект. Он вернет целевой объект.
Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
собственные length
свойство массива не копируется, потому что оно не перечисляется.
С такой функцией:
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()
строительство.
вы можете использовать аккумулятор aka 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}
ваш аккумулятор может быть любого типа для определенной цели. Например, чтобы поменять ключ и значение вашего объекта в массиве, pass []
:
[{ 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
; вы должны предоставить polyfill для браузеров, которые их не поддерживают (особенно IE8).
см. реализацию по умолчанию Mozilla.
для полноты, распространение ECMAScript 2015(ES6). Потребуется либо транспилер (Babel), либо среда, работающая по крайней мере ES6.
{ ...['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' }
вот метод 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
Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
простой способ в современном JavaScript-использовать Object.assign()
это не делает ничего, кроме копирования key: value из одного объекта в другой. В нашем случае, Array
дарит свойства new {}
.
Я закончил использование оператора распространения объектов, так как он является частью стандарта ECMAScript 2015 (ES6).
const array = ['a', 'b', 'c'];
console.log({...array});
// it outputs {0:'a', 1:'b', 2:'c'}
сделал следующее скрипка в качестве примера.
можно использовать Object.assign
и array.reduce
функция преобразования массива в объект.
var arr = [{a:{b:1}},{c:{d:2}}]
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
console.log(newObj)
пять лет спустя, есть хороший способ :)
Object.assign
был представлен в ECMAScript 2015.
Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
быстрый и грязный:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
начиная с Lodash 3.0.0 вы можете использовать _.toPlainObject
var obj = _.toPlainObject(['a', 'b', 'c']);
console.log(obj);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Если вы используете ES6, вы можете использовать Object.назначение и операторов
{ ...['a', 'b', 'c'] }
Если у вас есть вложенный массив как
var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
Я бы сделал это просто с Array.of()
. массив имеет возможность использовать его контекст в качестве конструктора.
примечание 2 функция является намеренно общим заводским методом; это не требует, чтобы это значение было конструктором массива. Поэтому он может быть передан или унаследован другими конструкторами это может быть вызвано одним числовым аргументом.
так мы можем связать Array.of()
функции и генерировать массив как объект.
function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);
С помощью Array.of()
можно даже сделать подкласс массива.
Это позволяет генерировать из массива объект с ключами, которые вы определяете в нужном вам порядке.
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;
};
вот рекурсивная функция, которую я только что написал. Это просто и хорошо работает.
// 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));
результаты:
Если вы используете angularjs, вы можете использовать angular.расширьте, тот же эффект с $.продлить в jQuery.
var newObj = {};
angular.extend(newObj, ['a','b','c']);
.reduce((o,v,i)=>(o[i]=v,o), {})
[docs]
или более многословным
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'}
etc...
const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript
преобразовать в объект на основе значения {css : 'css is great'}
etc...
const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great
используя 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 в вы можете сделать что-то вроде:
const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
вы можете использовать такую функцию:
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}), {})
let i = 0;
let myArray = ["first", "second", "third", "fourth"];
const arrayToObject = (arr) =>
Object.assign({}, ...arr.map(item => ({[i++]: item})));
console.log(arrayToObject(myArray));
или использовать
myArray = ["first", "second", "third", "fourth"]
console.log({...myArray})
Я сталкивался с этой проблемой несколько раз и решил написать функцию, которая является как можно более общей. Посмотрите и не стесняйтесь изменять что-нибудь
function typeOf(obj) {
if ( typeof(obj) == 'object' ) {
if (obj.length)
return 'array';
else
return 'object';
} else
return typeof(obj);
}
function objToArray(obj, ignoreKeys) {
var arr = [];
if (typeOf(obj) == 'object') {
for (var key in obj) {
if (typeOf(obj[key]) == 'object') {
if (ignoreKeys)
arr.push(objToArray(obj[key],ignoreKeys));
else
arr.push([key,objToArray(obj[key])]);
}
else
arr.push(obj[key]);
}
}else if (typeOf(obj) == 'array') {
for (var key=0;key<obj.length;key++) {
if (typeOf(obj[key]) == 'object')
arr.push(objToArray(obj[key]));
else
arr.push(obj[key]);
}
}
return arr;
}