Який найкращий спосіб конвертувати:
['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
; ви повинні надати полізаповнення для браузерів, які не підтримують їх (особливо IE8).
Дивіться реалізацію Mozilla за замовчуванням .
Якщо ви використовуєте jquery:
$.extend({}, ['a', 'b', 'c']);
{0: 'a', 1: 'b', 2: 'c'}
- це очікуваний результат.
Для повноти розповсюдження ECMAScript 2015 (ES6). Знадобиться або транспілятор (Babel), або середовище, що працює принаймні ES6.
console.log(
{ ...['a', 'b', 'c'] }
)
Я, мабуть, написав би це так (оскільки дуже рідко я не матиму під рукою бібліотеку підкреслення):
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), {})
[документи]
або більше багатослівного
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]
[/docs]
? Було б корисніше зробити фрагменти коду виконаними.
Я б це зробив просто з Array.of()
. Масив має можливість використовувати його контекст як конструктор.
ПРИМІТКА 2 Функція - це навмисно загальний заводський метод; не потрібно, щоб його це значення було конструктором масиву. Тому він може бути переданий або успадкований іншими конструкторами, які можуть бути викликані одним числовим аргументом.
Тож ми можемо прив’язатись 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);
виведе "фарба", функція повинна мати масиви однакової довжини або ви отримаєте порожній об'єкт.
Ось оновлений метод
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?