Quel est le meilleur moyen de convertir:
['a','b','c']
à:
{
0: 'a',
1: 'b',
2: 'c'
}
ECMAScript 6 introduit le Object.assign
: facilement polyfillable
La méthode
Object.assign()
est utilisée pour copier les valeurs de tous propriétés énumérables propres d'un ou plusieurs objets source à une cible objet. Il retournera l'objet cible.
Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}
La propriété propre length
du tableau n'est pas copiée car elle n'est pas énumérable.
De plus, vous pouvez utiliser ES6 propagation syntaxe pour obtenir le même résultat:
{ ...['a', 'b', 'c'] }
Avec une fonction comme celle-ci:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
rv[i] = arr[i];
return rv;
}
Votre tableau est déjà plus ou moins juste un objet, mais les tableaux ont un comportement "intéressant" et spécial en ce qui concerne les propriétés nommées par un entier. Ce qui précède vous donnera un objet simple.
edit oh aussi vous voudrez peut-être rendre compte des "trous" dans le tableau:
function toObject(arr) {
var rv = {};
for (var i = 0; i < arr.length; ++i)
if (arr[i] !== undefined) rv[i] = arr[i];
return rv;
}
Dans les exécutions JavaScript modernes, vous pouvez utiliser la méthode .reduce()
:
var obj = arr.reduce(function(acc, cur, i) {
acc[i] = cur;
return acc;
}, {});
Celui-ci évite également les "trous" dans le tableau, car c'est ainsi que fonctionne .reduce()
.
Vous pouvez utiliser un accumulateur 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"
Passez un objet vide {}
comme point de départ; puis "augmente" progressivement cet objet . À la fin des itérations, result
sera {"0": "a", "1": "b", "2": "c"}
Si votre tableau est un ensemble d'objets paire paire clé-valeur:
[{ 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;
}, {});
produira: {a: 1, b: 2, c: 3}
Par souci d'exhaustivité, reduceRight
vous permet de parcourir votre tableau dans l'ordre inverse:
[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)
produira: {c:3, b:2, a:1}
Votre accumulateur peut être de tout type pour un but spécifique. Par exemple, pour échanger la clé et la valeur de votre objet dans un tableau, transmettez []
:
[{ 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
produira: [{1: "a"}, {2: "b"}, {3: "c"}]
Contrairement à map
, reduce
ne peut pas être utilisé comme mappage 1-1. Vous avez un contrôle total sur les éléments que vous souhaitez inclure ou exclure. Donc, reduce
vous permet d’atteindre ce que filter
fait, ce qui rend reduce
très polyvalent:
[{ 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
produira: [{2: "b"}, {3: "c"}]
Caution: reduce
et Object.key
font partie de ECMA 5th edition
; vous devriez fournir un polyfill aux navigateurs qui ne les prennent pas en charge (notamment IE8).
Voir une implémentation par défaut de Mozilla .
Si vous utilisez jQuery:
$.extend({}, ['a', 'b', 'c']);
Pour être complet, ECMAScript 2015 (ES6) spreading. Nécessite un transpiler (Babel) ou un environnement exécutant au moins ES6.
{ ...['a', 'b', 'c'] }
Je l’écrirais probablement de cette façon (car très rarement je n’aurai pas la bibliothèque underscorejs sous la main):
var _ = require('underscore');
var a = [ 'a', 'b', 'c' ];
var obj = _.extend({}, a);
console.log(obj);
// prints { '0': 'a', '1': 'b', '2': 'c' }
Voici une méthode O(1) ES2015 juste pour être complet.
var arr = [1, 2, 3, 4, 5]; // array, already an object
Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object
Surpris de ne pas voir -
Object.assign({}, your_array)
Object.assign({}, ['one', 'two']); // {0: 'one', 1: 'two'}
La méthode la plus simple en JavaScript moderne consiste à utiliser Object.assign()
qui ne copie que la clé: valeur d’un objet à un autre. Dans notre cas, Array
donne des propriétés au nouveau {}
.
J'ai fini par utiliser l'opérateur de propagation d'objet, car il fait partie de la norme ECMAScript 2015 (ES6).
const array = ['a', 'b', 'c'];
console.log({...array});
// it outputs {0:'a', 1:'b', 2:'c'}
Fait le suivant violon à titre d'exemple.
nous pouvons utiliser les fonctions Object.assign
et array.reduce
pour convertir un tableau en objet .
var arr = [{a:{b:1}},{c:{d:2}}]
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})
console.log(newObj)
Cinq ans plus tard, il y a un bon moyen :)
Object.assign
a été introduit dans ECMAScript 2015.
Object.assign({}, ['a', 'b', 'c'])
// {'0':'a', '1':'b', '2':'c'}
vous pouvez utiliser l'opérateur spread
x = [1,2,3,10]
{...x} // {0:1, 1:2, 2:3, 3:10}
Un rapide et sale:
var obj = {},
arr = ['a','b','c'],
l = arr.length;
while( l && (obj[--l] = arr.pop() ) ){};
En utilisant la syntaxe ES6 vous pouvez faire quelque chose comme:
const arr = ['a', 'b', 'c'];
const obj = {...arr}; // -> {0: "a", 1: "b", 2: "c"}
En utilisant javascript#forEach
on peut le faire
var result = {},
attributes = ['a', 'b','c'];
attributes.forEach(function(prop,index) {
result[index] = prop;
});
Avec ECMA6:
attributes.forEach((prop,index)=>result[index] = prop);
Depuis Lodash 3.0.0, vous pouvez utiliser _.toPlainObject
var obj = _.toPlainObject(['a', 'b', 'c']);
console.log(obj);
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>
Si vous utilisez ES6, vous pouvez utiliser Object.assign et l'opérateur spread.
{ ...['a', 'b', 'c'] }
Si vous avez un tableau imbriqué comme
var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))
Rapide et sale # 2:
var i = 0
, s = {}
, a = ['A', 'B', 'C'];
while( a[i] ) { s[i] = a[i++] };
Je le ferais simplement avec Array.of()
. Array of a la capacité d'utiliser son contexte en tant que constructeur.
NOTE 2 La fonction of est une méthode d'usine intentionnellement générique; il ne nécessite pas que sa cette valeur soit le constructeur Array . Par conséquent, il peut être transféré ou hérité par d'autres constructeurs qui peut être appelé avec un seul argument numérique.
Donc, nous pouvons lier Array.of()
à une fonction et générer un tableau comme objet.
function dummy(){};
var thingy = Array.of.apply(dummy,[1,2,3,4]);
console.log(thingy);
En utilisant Array.of()
on peut même faire un sous-classement de tableaux .
Voici une fonction récursive que je viens d'écrire. C'est simple et fonctionne bien.
// 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;
}
Voici un exemple ( 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));
Résultats:
Voici une solution en coffeescript
arrayToObj = (arr) ->
obj = {}
for v,i in arr
obj[i] = v if v?
obj
Cela vous permet de générer à partir d'un tableau un objet avec les clés que vous définissez dans l'ordre de votre choix.
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);
affichera "Paint", la fonction doit avoir des tableaux de longueur égale ou vous obtenez un objet vide.
Voici une méthode mise à jour
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), {})
[docs]
ou plus verbeux
var trAr2Obj = function (arr) {return arr.reduce((o,v,i)=>(o[i]=v,o), {});}
ou
var transposeAr2Obj = arr=>arr.reduce((o,v,i)=>(o[i]=v,o), {})
le plus court avec Vanilla JS
JSON.stringify([["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[i]=v,o}, {}))
=> "{"0":["a","X"],"1":["b","Y"]}"
un exemple plus complexe
[["a", "X"], ["b", "Y"]].reduce((o,v,i)=>{return o[v[0]]=v.slice(1)[0],o}, {})
=> Object {a: "X", b: "Y"}
encore plus court (en utilisant 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]
Si vous utilisez angularjs, vous pouvez utiliser angular.extend, le même effet avec $ .extend of jquery.
var newObj = {};
angular.extend(newObj, ['a','b','c']);
Si vous pouvez utiliser Map
ou Object.assign
, c'est très simple.
Créer un tableau:
const languages = ['css', 'javascript', 'php', 'html'];
La création ci-dessous crée un objet avec index en tant que clé:
Object.assign({}, languages)
Répliquer la même chose que ci-dessus avec Maps
Conversion en objet basé sur l'index {0 : 'css'}
etc ...
const indexMap = new Map(languages.map((name, i) => [i, name] ));
indexMap.get(1) // javascript
Convertir en un objet basé sur la valeur {css : 'css is great'}
etc ...
const valueMap = new Map(languages.map(name => [name, `${name} is great!`] ));
valueMap.get('css') // css is great
Vous pouvez utiliser une fonction comme celle-ci:
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;
};
Celui-ci devrait gérer les tableaux clairsemés plus efficacement.
let i = 0;
let myArray = ["first", "second", "third", "fourth"];
const arrayToObject = (arr) =>
Object.assign({}, ...arr.map(item => ({[i++]: item})));
console.log(arrayToObject(myArray));
Ou utiliser
myArray = ["first", "second", "third", "fourth"]
console.log({...myArray})
Ce n’est pas directement pertinent, mais je suis venu ici à la recherche d’une couche unique pour la fusion d’objets imbriqués tels que
const nodes = {
node1: {
interfaces: {if1: {}, if2: {}}
},
node2: {
interfaces: {if3: {}, if4: {}}
},
node3: {
interfaces: {if5: {}, if6: {}}
},
}
La solution consiste à utiliser une combinaison de réduction et de propagation d'objet:
const allInterfaces = nodes => Object.keys(nodes).reduce((res, key) => ({...res, ...nodes[key].interfaces}), {})
J'ai fait face à ce problème plusieurs fois et j'ai décidé d'écrire une fonction aussi générique que possible. Regardez et n'hésitez pas à modifier quoi que ce soit
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;
}
Utilisez la bibliothèque javascript lodash. Il existe une méthode simple _.mapKeys(object, [iteratee=_.identity])
cela peut faire la conversion.
J'utiliserais un trait de soulignement pour cela, mais si cela n'était pas disponible, j'utiliserais réduire avec une valeur initiale d'objet vide {}
>>> ['a', 'b', 'c'].reduce(function(p, c, i) {p[i] = c; return p}, {})
Object { 0="a", 1="b", 2="c"}
réduire devrait être largement disponible dans la plupart des navigateurs aujourd'hui, voir MDN
Plus de navigateur pris en charge consiste à utiliser une boucle normale, quelque chose comme:
const arr = ['a', 'b', 'c'],
obj = {};
for (let i=0; i<arr.length; i++) {
obj[i] = arr[i];
}
Mais la manière moderne pourrait aussi utiliser le opérateur de propagation, comme:
{...arr}
Ou attribution d'objet:
Object.assign({}, ['a', 'b', 'c']);
Les deux vont retour:
{0: "a", 1: "b", 2: "c"}
Il est facile d’utiliser javascript réduire:
["a", "b", "c", "d"].reduce(function(previousValue, currentValue, index) {
previousValue[index] = currentValue;
return previousValue;
},
{}
);
Vous pouvez consulter Array.prototype.reduce (), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
FWIW, une autre approche récente consiste à utiliser le nouveau Object.fromEntries
avec Object.entries
comme suit:
const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));
... qui permet d'éviter de stocker des éléments de tableau fragmentés sous la forme undefined
ou null
et de conserver les clés non indexées (par exemple, les entiers non positifs/non numériques).
On peut souhaiter ajouter arr.length
, cependant, car cela n’est pas inclus:
obj.length = arr.length;
ES5 - Solution:
En utilisant Array fonction prototype 'Push' et 'apply' vous pouvez remplir l'objet avec les éléments du tableau.
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
tableau initial et convertira en un objet avec des clés qui sera l’élément unique d’un tableau et la valeur de la clé sera le nombre de répétitions
var jsTechs = ['angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'angular', 'react', 'ember', 'vanilaJS', 'ember', 'react', 'react', 'vanilaJS', 'react', 'vanilaJS', 'vanilaJS']
var initialValue = {
Java : 4
}
var reducerFunc = function reducerFunc (initObj, jsLib) {
if (!initObj[jsLib]) {
initObj[jsLib] = 1
} else {
initObj[jsLib] += 1
}
return initObj
}
var finalResult = jsTechs.reduce(reducerFunc, initialValue)
console.log(finalResult)
La méthode ci-dessous convertirait un tableau en objet avec une clé donnée.
/**
* Converts array to object
* @param {Array} array
* @param {string} key (optional)
*/
Array.prototype.ArrayToObject = function(key) {
const array = this;
const obj = {};
array.forEach((element, index) => {
if(!key) {
obj[index] = element;
} else if ((element && typeof element == 'object' && element[key])) {
obj[element[key]] = element;
}
});
return obj;
}
Pour Ex -
[{name: 'test'}, {name: 'test1'}]. ArrayToObject ('name');
donnerait
{test: {name: 'test'}, test1: {name: 'test1'}}
et la clé cas n'est pas fournie en tant que paramètre de la méthode
i.e. [{name: 'test'}, {name: 'test1'}].ArrayToObject();
donnerait
{0: {name: 'test'}, 1: {name: 'test1'}}
Le moyen le plus simple de procéder est le suivant:
const arr = ['a','b','c'];
let obj = {}
function ConvertArr(arr) {
if (typeof(arr) === 'array') {
Object.assign(obj, arr);
}
De cette façon, il ne s'exécutera que s'il s'agit d'un tableau. Cependant, vous pouvez l'exécuter avec let variable d'objet global ou sans, à vous de choisir. Si vous exécutez sans let, il suffit de faire Object.assign ({}, arr).
Si vous aimez oneliners, et IE8 n'est plus un problème (comme il se doit)
['a','b','c'].reduce((m,e,i) => Object.assign(m, {[i]: e}), {});
Allez-y et essayez-le sur la console du navigateur
Cela pourrait être plus verbeux comme ceci:
['a','b','c'].reduce(function(memo,Elm,idx) {
return Object.assign(memo, {[idx]: Elm});
}, {});
Mais exclut toujours IE8. Si IE8 est un must, vous pouvez utiliser le lodash/underscore comme ça:
_.reduce(['a','b','c'], function(memo,Elm,idx) {
return Object.assign(memo, {[idx]: Elm});
}, {})