javascript - Hur konverterar man en array till ett objekt?


Vad är det bästa sättet att konvertera:

['a','b','c']

till :

{
  0: 'a',
  1: 'b',
  2: 'c'
}

Svar #1

ECMAScript 6 introducerar den lätt polyfyllbara Object.assign:

Metoden Object.assign() används för att kopiera värdena av alla uppräkneliga egna egenskaper från ett eller flera källobjekt till ett målobjekt. Den kommer att returnera målobjektet.

Object.assign({}, ['a','b','c']); // {0:"a", 1:"b", 2:"c"}

Den egna length-egenskapen hos arrayen kopieras inte eftersom den inte är uppräkningsbar.

Du kan också använda ES8 spread-syntax på objekt för att uppnå samma resultat:

{ ...['a', 'b', 'c'] }

För anpassade nycklar kan du använda reduce:

['a', 'b', 'c'].reduce((a, v) => ({ ...a, [v]: v}), {}) 
// { a: "a", b: "b", c: "c" }

Svar #2

Med en funktion som denna:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    rv[i] = arr[i];
  return rv;
}

Din array är redan mer eller mindre bara ett objekt, men arrayer har viss "intressant" och speciellt beteende när det gäller egenskaper med heltalsnamn. Ovanstående kommer att ge dig ett vanligt objekt.

redigera åh du kanske också vill ta hänsyn till "hål" i arrayen:

function toObject(arr) {
  var rv = {};
  for (var i = 0; i < arr.length; ++i)
    if (arr[i] !== undefined) rv[i] = arr[i];
  return rv;
}

I moderna JavaScript-runtime-miljöer kan du använda .reduce()-metoden:

var obj = arr.reduce(function(acc, cur, i) {
  acc[i] = cur;
  return acc;
}, {});

Den där undviker också "hål" i arrayen, eftersom det är så .reduce() fungerar.

Svar #3

Du kan använda en ackumulator, även kallad 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"

Skicka ett tomt objekt {} som utgångspunkt; sedan kan du "förstärka" det objektet stegvis. I slutet av iterationerna kommer result att vara {"0": "a", "1": "b", "2": "c"}

Om din array är en uppsättning nyckel-värdepar-objekt:

[{ 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;
}, {});

kommer att producera: {a: 1, b: 2, c: 3}

För fullständighetens skull tillåter reduceRight dig att iterera över din array i omvänd ordning:

[{ a: 1},{ b: 2},{ c: 3}].reduceRight(/* same implementation as above */)

kommer att producera: {c:3, b:2, a:1}

Din ackumulator kan vara av vilken typ som helst för ditt specifika syfte. Till exempel, för att byta plats på nyckeln och värdet i ditt objekt i en array, skicka []:

[{ 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

kommer att producera: [{1: "a"}, {2: "b"}, {3: "c"}]

Till skillnad från map kan reduce inte användas som en 1-1-avbildning. Du har full kontroll över de objekt du vill inkludera eller exkludera. Därför tillåter reduce dig att uppnå det som filter gör, vilket gör reduce mycket mångsidig:

[{ 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

kommer att producera: [{2: "b"}, {3: "c"}]

Varning: reduce och Object.key är en del av ECMA 5:e utgåvan; du bör tillhandahålla en polyfill för webbläsare som inte stöder dem (främst IE8).

Se en standardimplementering av Mozilla.

Svar #4

Om du använder jquery:

$.extend({}, ['a', 'b', 'c']);

Svar #5

För fullständighetens skull, ECMAScript 2015 (ES6) spridning. Kommer att kräva antingen en transpiler (Babel) eller en miljö som kör minst ES6.

console.log(
   { ...['a', 'b', 'c'] }
)

Svar #6

Inte många personer här kommenterade Object.fromEntries, jag gillar det verkligen, eftersom det är renare och fungerar enkelt med TypeScript, utan att behöva bry sig för mycket om generiska typer och sådant. Det tillåter också anpassade nycklar med map, om det behövs. Nackdelar: du kommer behöva en extra map om du vill ha en anpassad nyckel. T.ex.:

const tags = [
  { name: 'AgeGroup', value: ageGroup },
  { name: 'ApparelTypes', value: apparelTypes },
  { name: 'Brand', value: brand },
  // ...
]

const objectTags = Object.fromEntries(tags.map((t) => [t.name, t.value]))

/*
{
  AgeGroup: 'Adult',
  Apparel: 'Creeper, Jacket'
  Brand: '',
  // ...
}
*/

Svar #7

Om du vill använda en av egenskaperna hos de itererade objekten som nyckel, till exempel:

// from:
const arr = [
    {
        sid: 123,
        name: 'aaa'
    },
    {
        sid: 456,
        name: 'bbb'
    },
    {
        sid: 789,
        name: 'ccc'
    }
];
// to:
{
  '123': { sid: 123, name: 'aaa' },
  '456': { sid: 456, name: 'bbb' },
  '789': { sid: 789, name: 'ccc' }
}

Använd :

const result = arr.reduce((obj, cur) => ({...obj, [cur.sid]: cur}), {})

Svar #8

Jag skulle förmodligen skriva det på det här sättet (eftersom väldigt sällan kommer jag inte ha underscorejs-biblioteket till hands):

var _ = require('underscore');

var a = [ 'a', 'b', 'c' ];
var obj = _.extend({}, a);
console.log(obj);
// prints { '0': 'a', '1': 'b', '2': 'c' }

Svar #9

vi kan använda Object.assign och array.reduce funktionen för att konvertera en Array till ett Objekt.

var arr = [{a:{b:1}},{c:{d:2}}] 
var newObj = arr.reduce((a, b) => Object.assign(a, b), {})

console.log(newObj)

Svar #10

Här är en O(1) ES2015-metod bara för fullständighetens skull.

var arr = [1, 2, 3, 4, 5]; // array, already an object
Object.setPrototypeOf(arr, Object.prototype); // now no longer an array, still an object

Svar #11

För vad det är värt, ett annat nyligen närmat sätt är att använda den nya Object.fromEntries tillsammans med Object.entries på följande sätt:

const arr = ['a','b','c'];
arr[-2] = 'd';
arr.hello = 'e';
arr.length = 17;
const obj = Object.fromEntries(Object.entries(arr));

...vilket gör det möjligt att undvika att lagra glesa arrayelement som undefined eller null och bevarar icke-indexerade (t.ex. icke-positiva heltal/icke-numeriska) nycklar.

{ 0: "a", 1: "b", 2: "c", "-2": "d", hej: "e" }

(Samma resultat här som med @Paul Draper:s Object.assign-svar.)

Man kan önska att lägga till arr.length, men eftersom det inte är inkluderat:

obj.length = arr.length;

Svar #12

Om din array innehåller 2-element-arrayer där det första elementet är nyckeln och det andra elementet är värdet kan du enkelt konvertera till ett objekt med reduce.

[
  ["key1","value1"], 
  ["key2", "value2"], 
  ["key3", "value3"]
]
.reduce((acc, [key, value])=>({...acc, [key]: value}), {});

Resultat :

{  
  key1: 'value1',   
  key2: 'value2', 
  key3: 'value3'  
}  

Svar #13

Genom att använda javascript#forEach kan man göra detta

var result = {},
    attributes = ['a', 'b','c'];

attributes.forEach(function(prop,index) {
  result[index] = prop;
});

Med ECMA6:

attributes.forEach((prop,index)=>result[index] = prop);

Svar #14

Det kortaste svaret: (med destrukturering)

const obj = { ...input }

Exempel :

const inputArray = ["a", "b", "c"]
const outputObj = { ...inputArray }

Svar #15

Om du använder ES6 kan du använda Object.assign och spridningsoperatorn

{ ...['a', 'b', 'c'] }

Om du har en nästlad array som

var arr=[[1,2,3,4]]
Object.assign(...arr.map(d => ({[d[0]]: d[1]})))

Relaterade artiklar