Jaki jest najlepszy sposób konwersji:
['a','b','c']
do:
{
0: 'a',
1: 'b',
2: 'c'
}
_.toPlainObject
. Np .:var myObj = _.toPlainObject(myArr)
Jaki jest najlepszy sposób konwersji:
['a','b','c']
do:
{
0: 'a',
1: 'b',
2: 'c'
}
_.toPlainObject
. Np .:var myObj = _.toPlainObject(myArr)
Odpowiedzi:
ECMAScript 6 wprowadza łatwą do wielokrotnego napełniania Object.assign
:
Object.assign()
Sposób jest stosowany w celu skopiowania wartości wszystkich przeliczalnych właściwości własnych od jednego lub większej liczby obiektów źródłowych do obiektu docelowego. Zwróci obiekt docelowy.
Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
Własna length
właściwość tablicy nie jest kopiowana, ponieważ nie można jej wyliczyć.
Możesz także użyć składni spreadu ES6, aby osiągnąć ten sam wynik:
{ ...['a', 'b', 'c'] }
{ ...[sortedArray]}
Dzięki takiej funkcji:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
Twoja tablica jest już mniej więcej obiektem, ale tablice mają pewne „interesujące” i specjalne zachowanie w odniesieniu do właściwości o nazwach całkowitych. Powyższe da ci prosty przedmiot.
edytuj och też możesz chcieć uwzględnić „dziury” w tablicy:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) rv[i] = arr[i];
return rv;
}
W nowoczesnych środowiskach wykonawczych JavaScript możesz użyć .reduce()
metody:
var obj = arr.reduce(function(acc, cur, i) {
acc[i] = cur;
return acc;
}, {});
Ten pozwala także uniknąć „dziur” w tablicy, ponieważ tak to .reduce()
działa.
[]
), jeśli nie zamierzasz używać liczbowych kluczy właściwości i właściwości „length”.
const obj = arr.reduce((obj, cur, i) => { return { ...obj, [i]: cur }; }, {});
const obj = arr.reduce((obj, cur, i) => ({ ...obj, [i]: cur }), {});
Możesz użyć akumulatora 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"
Podaj pusty obiekt {}
jako punkt początkowy; następnie „powiększaj” ten obiekt stopniowo. Pod koniec iteracji result
będzie{"0": "a", "1": "b", "2": "c"}
Jeśli tablica jest zbiorem obiektów pary klucz-wartość:
[{ 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;
}, {});
będzie produkować: {a: 1, b: 2, c: 3}
Ze względu na kompletność, reduceRight
możesz iterować po tablicy w odwrotnej kolejności:
[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)
będzie produkować: {c:3, b:2, a:1}
Twój akumulator może być dowolnego rodzaju do określonego celu. Na przykład, aby zamienić klucz i wartość obiektu w tablicy, przekaż []
:
[{ 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
będzie produkować: [{1: "a"}, {2: "b"}, {3: "c"}]
W przeciwieństwie do map
, reduce
nie może być stosowany jako mapowanie 1-1. Masz pełną kontrolę nad elementami, które chcesz uwzględnić lub wykluczyć. Dlatego reduce
pozwala osiągnąć to filter
, co czyni, co czyni reduce
bardzo wszechstronnym:
[{ 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
będzie produkować: [{2: "b"}, {3: "c"}]
Uwaga : reduce
i Object.key
są częścią ECMA 5th edition
; powinieneś dostarczyć polifill dla przeglądarek, które ich nie obsługują (zwłaszcza IE8).
Zobacz domyślną implementację Mozilli .
Jeśli używasz jquery:
$.extend({}, ['a', 'b', 'c']);
{0: 'a', 1: 'b', 2: 'c'}
oczekiwanym rezultatem.
Dla kompletności, rozpowszechnianie ECMAScript 2015 (ES6). Będzie wymagał transpilatora (Babel) lub środowiska z co najmniej ES6.
console.log(
{ ...['a', 'b', 'c'] }
)
Prawdopodobnie napisałbym to w ten sposób (ponieważ bardzo rzadko nie będę mieć pod ręką biblioteki 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);
zrobiłby to zadanie. Ponadto, jeśli iterujesz przez tablice, powiedziałbym, że _.each
byłoby bardziej odpowiednie niż _.map
. Podsumowując, nie jest to dobra odpowiedź na kilku poziomach.
Oto metoda O (1) ES2015 tylko dla kompletności.
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
własności. (3) element jest jeszcze tablicą Array.isArray(arr) === true
. (4) Specjalne zachowania tablicowe nie są usuwane, np. arr.length = 0
Usuwa wszystkie indeksy. (5) Dlatego myślę, że Object.assign
jest znacznie lepszy .
Array.isArray
wraca tutaj true
po „przedmiot”, chociaż instanceof Array
nie ...
Zaskoczony nie widzieć -
console.log(
Object.assign({}, ['a', 'b', 'c'])
)
{ "first":"a", "second":"b","third":"c" }
z naprawionymi kluczami - Szukam zniszczenia
możemy użyć funkcji Object.assign
i array.reduce
przekonwertować tablicę na obiekt.
var arr = [{a:{b:1}},{c:{d:2}}]
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
console.log(newObj)
Skończyło się na użyciu operatora rozprzestrzeniania obiektów, ponieważ jest on częścią standardu 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'}
Prostym sposobem we współczesnym JavaScript jest użycie, Object.assign()
które nie robi nic poza kopiowaniem klucza: wartości z jednego obiektu do drugiego. W naszym przypadku Array
przekazuje nieruchomości na nowy {}
.
O.assign
ale brakowało wyjaśnienia. Obecnie {...array}
W przypadku ES2016 operator rozkładania dla obiektów. Uwaga: dzieje się to po ES6, więc transpiler będzie musiał zostać dostosowany.
const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
Pięć lat później jest dobry sposób :)
Object.assign
został wprowadzony w ECMAScript 2015.
Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
Za pomocą javascript#forEach
jednego można to zrobić
var result = {},
attributes = ['a', 'b','c'];
attributes.forEach(function(prop,index) {
result[index] = prop;
});
Z ECMA6:
attributes.forEach((prop,index)=>result[index] = prop);
FWIW, jednym z ostatnich ostatnich podejść jest użycie nowego Object.fromEntries
wraz z Object.entries
następującymi:
const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));
... co pozwala uniknąć przechowywania rzadkich elementów tablicy jako undefined
lubnull
i zachowuje klucze nieindeksowane (np. nie dodatnie liczby całkowite / nienumeryczne).
Można arr.length
jednak dodać , ponieważ nie jest to uwzględnione:
obj.length = arr.length;
możesz użyć operatora rozprzestrzeniania
x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Jeśli używasz ES6, możesz użyć Object.assign i operatora rozkładania
{ ...['a', 'b', 'c'] }
Jeśli masz zagnieżdżoną tablicę jak
var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
new Map([['key1', 'value1'], ['key2', 'value2']]);
Szybki i brudny:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
{0:"c", 1:"b", 2:"a"}
. Możesz unshift
zamiast tego pop
lub (lepiej) zacząć od i=arr.length-1
i zamiast tego zmniejszyć.
l = arr.length
, a potem while (l && (obj[--l] = arr.pop())){}
(zdaję sobie sprawę, że to jest stare, ale dlaczego nie uprościć go jeszcze bardziej).
Szybki i brudny # 2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( a[i] ) { s[i] = a[i++] };
i < a.length
zamiast a[i]
.
Od Lodash 3.0.0 możesz używać _.toPlainObject
var obj = _.toPlainObject(['a', 'b', 'c']);
console.log(obj);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Oto funkcja rekurencyjna, którą właśnie napisałem. To proste i działa dobrze.
// 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;
}
Oto przykład ( 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));
Wyniki:
['a' = '1', 'b' = '2', 'c' = '3']
i chcesz, żeby {a: 1, b: 2, c: 3}
to działało idealnie.
.reduce((o,v,i)=>(o[i]=v,o), {})
[dokumenty]
lub bardziej szczegółowe
var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}
lub
var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})
najkrótszy z waniliowym JS
JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
=> "{"0":["a","X"],"1":["b","Y"]}"
bardziej złożony przykład
[["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
=> Object {a: "X", b: "Y"}
jeszcze krótszy (przy użyciu 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]
? Przydałoby się uczynienie fragmentów kodu wykonywalnymi.
Zrobiłbym to po prostu Array.of()
. Tablica ma możliwość wykorzystania kontekstu jako konstruktora.
UWAGA 2 Funkcja jest celowo ogólną metodą fabryczną; nie wymaga, aby ta wartość była konstruktorem Array. Dlatego może być przenoszony lub dziedziczony przez inne konstruktory, które mogą być wywoływane za pomocą pojedynczego argumentu numerycznego.
Możemy więc powiązać Array.of()
się z funkcją i wygenerować obiekt podobny do tablicy.
function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);
Korzystając z niej Array.of()
można nawet dokonać podklasowania tablicy .
Jeśli możesz użyć Map
lubObject.assign
, jest to bardzo łatwe.
Utwórz tablicę:
const languages = ['css', 'javascript', 'php', 'html'];
Poniżej utworzono obiekt z indeksem jako kluczami:
Object.assign({}, languages)
Powtórz to samo co powyżej w Mapach
Konwertuje na obiekt oparty na indeksie {0 : 'css'}
itp ...
const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript
Konwertuj na obiekt oparty na wartości {css : 'css is great'}
itp ...
const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great
Prosta i bezczelna metoda szybkiego konwertowania tablicy przedmiotów na obiekt
function arrayToObject( srcArray ){
return JSON.parse( JSON.stringify( srcArray ) );
}
Więc używaj go tak ...
var p = [0,2,3,'pork','pie',6];
obj = new arrayToObject( p );
console.log( obj[3], obj[4] )
// expecting `pork pie`
Wynik:
pork pie
Sprawdzanie typu:
typeof obj
"object"
I rzeczy nie byłyby kompletne, gdyby nie było prototypowej metody
Array.prototype.toObject =function(){
return JSON.parse( JSON.stringify( this ) );
}
Za pomocą:
var q = [0,2,3,'cheese','whizz',6];
obj = q.toObject();
console.log( obj[3], obj[4] )
// expecting `cheese whizz`
Wynik:
cheese whizz
* UWAGA: nie ma procedury nazewnictwa, więc jeśli chcesz mieć określone nazwy, musisz kontynuować korzystanie z istniejących metod poniżej.
Starsza metoda
Umożliwia to generowanie z tablicy obiektu z kluczami zdefiniowanymi w żądanej kolejności.
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);
wyświetli „malować”, funkcja musi mieć tablice o równej długości lub otrzymasz pusty obiekt.
Oto zaktualizowana metoda
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));
Albo użyj
myArray = ["first", "second", "third", "fourth"]
console.log({...myArray})
ES5 - Rozwiązanie:
Za pomocą prototypowej funkcji Array „push” i „Apply” można wypełnić obiekt elementami tablicy.
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}
Więcej obsługiwanych przeglądarek i bardziej elastyczny sposób korzystania z normalnej pętli , na przykład:
const arr = ['a', 'b', 'c'],
obj = {};
for (let i=0; i<arr.length; i++) {
obj[i] = arr[i];
}
Ale również nowoczesnym sposobem może być użycie operatora rozprzestrzeniania , takiego jak:
{...arr}
Lub Przypisanie obiektu :
Object.assign({}, ['a', 'b', 'c']);
Oba powrócą :
{0: "a", 1: "b", 2: "c"}
Możesz użyć takiej funkcji:
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;
};
Ten powinien efektywniej obsługiwać rzadkie tablice.
Oto rozwiązanie w 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?