Utwórz obiekt z tablicy

91

Chcę utworzyć obiekt z listy tablicy. Mam tablicę dynamiczną, która ma wyglądać następująco:

var dynamicArray = ["2007", "2008", "2009", "2010"];

i przy pomocy javascript es6 chcę stworzyć taki obiekt:

const obj = {
    2007: {
        x: width / 5,
        y: height / 2
    },
    2008: {
        x: (2 / 5) * width,
        y: height / 2
    },
    2009: {
        x: (3 / 5) * width,
        y: height / 2
    },
    2010: {
        x: (4 / 5) * width,
        y: height / 2
    }
}

nie przejmuj się obiektami wewnętrznymi, ale chciałem stworzyć taką strukturę:

 obj = {
      2007: ...,
      2008: ...,
      ...
    }

Proszę o pomoc, dzięki.

Hussain Dehgamwala
źródło
2
W porządku. Czego próbowałeś? Gdzie utkniesz? Jakie badania przeprowadziłeś? Czy spojrzałeś na to na przykład?
TJ Crowder

Odpowiedzi:

217

Po prostu

 const obj = {};

 for (const key of yourArray) {
      obj[key] = whatever;
 }

lub jeśli wolisz styl „funkcjonalny”:

 const obj = yourArray.reduce((o, key) => Object.assign(o, {[key]: whatever}), {});

używając nowoczesnego operatora rozprzestrzeniania obiektów:

const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})

Przykład:

[
  { id: 10, color: "red" },
  { id: 20, color: "blue" },
  { id: 30, color: "green" }
].reduce((acc, cur) => ({ ...acc, [cur.color]: cur.id }), {})

Wynik:

{red: 10, blue: 20, green: 30}

Oto jak to działa:

reducejest inicjowany pustym obiektem (pustym {}na końcu), dlatego zmienne pierwszej iteracji są acc = {} cur = { id: 10, color: "red" }. Funkcja zwraca obiekt - dlatego treść funkcji jest umieszczona w nawiasach => ({ ... }). Operator spreadu nie robi nic w pierwszej iteracji, więcred: 10 jest ustawiany jako pierwszy element.

W drugiej iteracji zmienne to acc = { red: 10 } cur = { id: 20, color: "blue" }. Tutaj operator spreadu rozwija się acc i funkcja zwraca{ red: 10, blue: 20 } .

Trzecia iteracja acc = { red: 10, blue: 20 } cur = { id: 30, color: "green" }, więc gdy accjest rozproszona wewnątrz obiektu, nasza funkcja zwraca wartość końcową.

Georg
źródło
1
Dzięki! Działało zgodnie z wymaganiami. Nigdy nie wiedziałem o array.reducefunkcji.
Hussain Dehgamwala
1
Jeśli wolisz funkcjonalny styl, a ja tak, powinieneś użyć const. Właściwie powinieneś go używać niezależnie. Ponadto, jeśli masz dostęp do składni ES Next rest / spread (powiedzmy przez TypeScript lub Babel), możesz pisać, const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})a nawet unikać mutowania nasion: p
Aluan Haddad
1
@AluanHaddad: dobra sugestia, przekonwertowałem post na CW, nie krępuj się edytować.
georg
({... o, [klucz]: kandydatDoc [klucz]}) .. gdzie kandydatDoc jest jakimś pojo. Chcę wziąć tylko wartości, które są zdefiniowane w Candidoc. Ale jestem zdezorientowany z rodzicem, który on nie wydaje się mieć „zwrotu” lub stwierdzenia „if”, aby zadziałało. Czy mógłbyś wskazać mi właściwy kierunek - nie boję się czytać dokumentacji.
terary
1
@cameck: dzięki, post jest CW, zapraszam do edycji.
georg
38

Nowy Object.fromEntries, pochodzący z ECMAScript 2019, jeszcze bardziej ułatwia przekształcanie wartości z tablicy na klucze w obiekcie takim jak poniżej

const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map(year => [year, {
    something: "based",
    on: year
  }])
)

console.log(obj)

Abderrahmane TAHRI JOUTI
źródło
21

w js z funkcją es6 redukuj dla tablicy Robię to w ten sposób

let x = [1,2,3]
let y = x.reduce((acc, elem) => {
  acc[elem] = elem // or what ever object you want inside
  return acc
}, {})
console.log(y) // {1:1, 2:2, 3:3}
Ralexrdz
źródło
3
jeszcze krócej:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
exebook
5
var keys = ['key1', 'key2', 'key3']

var object = Object.assign({}, ...Object.entries({...keys}).map(([a,b]) => ({ [b]: 'someValue' })))
console.log(object)

To wyprodukuje

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }
Alok Singh Mahor
źródło
0

Odkryłem, że możesz po prostu użyć Object.assign()bezpośrednio z operatorem spreadu. Nie ma potrzeby wprowadzania większej złożoności za pomocą a reducelub mapfunkcji.

Po prostu zrób, Object.assign(...yourArray, {})a uzyskasz pożądany efekt. Jeśli zamiast tego chcesz scalić swoją tablicę obiektów w inny obiekt, możesz również wywołaćObject.assign(...yourArray, yourObject) a to również będzie działać dobrze.

Możesz również użyć tej samej metody do scalenia dwóch tablic w jeden obiekt, nawet jeśli jedna z tablic nie zawiera obiektów, ale tylko wartości pierwotne - jednak jeśli to zrobisz, musisz upewnić się, że co najmniej jedna z tablic zawiera tylko obiekty jako prymityw będzie miał domyślny indeks jako the key, więc jeśli istnieje zduplikowany klucz, pojawią się błędy.

Jednak dla celów PO nie ma ryzyka takich błędów, ponieważ łączy się on z pustym obiektem, co jest najbezpieczniejsze.

const arr = [
  { a: 0 },
  { c: 1 },
  { e: 2 },
];

const obj = Object.assign(...arr, {});

console.log(obj)

// Results to:
// Object { a: 0, c: 1, e: 2 }
Aasmund Berge Endresen
źródło
-4

możesz użyć:

     dynamicArray.map(value => ({'key': value, 'val': 'whatever you want'}));

wprowadź opis obrazu tutaj

jilykate
źródło
3
Nie tak, jak chcę !!
Hussain Dehgamwala