Какой лучший способ конвертировать:
['a','b','c']
чтобы:
{
0: 'a',
1: 'b',
2: 'c'
}
_.toPlainObject
. Пример:var myObj = _.toPlainObject(myArr)
Какой лучший способ конвертировать:
['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
свойство массива не копируется, поскольку оно не перечисляемо.
Кроме того, вы можете использовать синтаксис ES6 для достижения того же результата:
{ ...['a', 'b', 'c'] }
{ ...[sortedArray]}
С такой функцией:
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()
работает.
[]
), если вы не собираетесь использовать числовые ключи свойств и свойство "length".
const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
Вы можете использовать аккумулятор ака 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
; Вы должны предоставить polyfill для браузеров, которые их не поддерживают (особенно IE8).
Смотрите реализацию по умолчанию от 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
. В общем, это не очень хороший ответ на нескольких уровнях.
Вот метод 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) Поэтому я думаю, что Object.assign
намного лучше .
Array.isArray
возвращается true
за "объект" здесь, хотя instanceof Array
не ...
Удивлен не видеть -
console.log(
Object.assign({}, ['a', 'b', 'c'])
)
{ "first":"a", "second":"b","third":"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)
В итоге я использовал оператор распространения объектов, поскольку он является частью стандарта ECMAScript 2015 (ES6).
const array = ['a', 'b', 'c'];
console.log({...array});
// it outputs {0:'a', 1:'b', 2:'c'}
Сделал следующую скрипку в качестве примера.
Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
В современном JavaScript простой способ - использовать Object.assign()
только копирование ключа: значения из одного объекта в другой. В нашем случае Array
жертвует свойства на новый {}
.
O.assign
но это не объяснялось. В настоящее время деструктурирование массива в объект является способом ( {...array}
)
Для ES2016, оператор распространения для объектов. Примечание: это после ES6 и поэтому необходимо настроить транспортер.
const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
Пять лет спустя, есть хороший способ :)
Object.assign
был представлен в ECMAScript 2015.
Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
Используя javascript#forEach
один можно сделать это
var result = {},
attributes = ['a', 'b','c'];
attributes.forEach(function(prop,index) {
result[index] = prop;
});
С ECMA6:
attributes.forEach((prop,index)=>result[index] = prop);
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
и сохраняет неиндексные (например, не положительно-целые / не числовые) ключи.
arr.length
Тем не менее, можно добавить , что это не входит:
obj.length = arr.length;
Вы можете использовать спред оператора
x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Если вы используете 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( a[i] ) { s[i] = a[i++] };
i < a.length
вместо a[i]
.
Начиная с 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>
Вот рекурсивная функция, которую я только что написал. Это просто и хорошо работает.
// 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));
Результаты:
['a' = '1', 'b' = '2', 'c' = '3']
и хотите, чтобы {a: 1, b: 2, c: 3}
это работало идеально.
.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]
? Было бы более полезно сделать исполняемые фрагменты кода.
Я бы сделал это просто с Array.of()
. Массив имеет возможность использовать его контекст в качестве конструктора.
ПРИМЕЧАНИЕ 2. Функция является намеренно общим заводским методом; это не требует, чтобы это значение было конструктором Array. Поэтому он может быть передан или унаследован другими конструкторами, которые могут быть вызваны с одним числовым аргументом.
Таким образом, мы можем связываться Array.of()
с функцией и генерировать массив, подобный объекту.
function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);
Используя Array.of()
его, можно даже выполнять подклассификацию массива .
Если вы можете использовать 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
Простой и дерзкий метод быстрого преобразования массива предметов в объект
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;
};
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})
ES5 - Решение:
Используя функции прототипа Array «push» и «apply», вы можете заполнить объект элементами массива.
var arr = ['a','b','c'];
var obj = new Object();
Array.prototype.push.apply(obj, arr);
console.log(obj); // { '0': 'a', '1': 'b', '2': 'c', length: 3 }
console.log(obj[2]); // c
{ name: a, div :b, salary:c}
Более поддерживаемый браузер и более гибкий способ сделать это, используя обычный цикл , что-то вроде:
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"}
Вы можете использовать такую функцию:
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;
};
Этот должен обрабатывать разреженные массивы более эффективно.
Вот решение в coffeescript
arrayToObj = (arr) ->
obj = {}
for v,i in arr
obj[i] = v if v?
obj
obj[i] = v for v,i in arr when v?