Создать объект из массива

91

Я хочу создать объект из списка массива. У меня есть динамический массив, который должен выглядеть так:

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

и с некоторым javascript es6 я хочу создать такой объект:

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
    }
}

не беспокойтесь о внутренних объектах, просто хотел создать такую ​​структуру:

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

Пожалуйста, помогите, спасибо.

Хуссейн Дехгамвала
источник
2
Хорошо. Что пробовали? Где ты застрял? Какие исследования вы провели? Вы, например, смотрели на это ?
TJ Crowder

Ответы:

217

Просто

 const obj = {};

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

или если вы предпочитаете «функциональный» стиль:

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

используя современный оператор распространения объекта:

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

Пример:

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

Вывод:

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

Вот как это работает:

reduceинициализируется пустым объектом (пустым {}в конце), поэтому переменные первой итерации acc = {} cur = { id: 10, color: "red" }. Функция возвращает объект - поэтому тело функции заключено в круглые скобки => ({ ... }). Оператор распространения ничего не делает на первой итерации, поэтому red: 10устанавливается как первый элемент.

На второй итерации переменные есть acc = { red: 10 } cur = { id: 20, color: "blue" }. Здесь оператор распространения расширяется, acc а функция возвращается { red: 10, blue: 20 }.

Третья итерация acc = { red: 10, blue: 20 } cur = { id: 30, color: "green" }, поэтому, когда accона распространяется внутри объекта, наша функция возвращает окончательное значение.

georg
источник
1
Благодаря! Работало как надо. Я никогда не знал о array.reduceфункциях.
Хуссейн Дехгамвала
1
Если вы предпочитаете функциональный стиль, а я предпочитаю, вам следует использовать const. На самом деле вы должны использовать его в любом случае. Кроме того, если у вас есть доступ к синтаксису отдыха / распространения ES Next (скажем, через TypeScript или Babel), вы можете писать const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})и даже избегать мутации семени: p
Алуан Хаддад
1
@AluanHaddad: хорошее предложение, конвертировал пост в CW, не стесняйтесь редактировать.
georg
({... о, [ключ]: кандидатДок [ключ]}) .. где кандидатДок - это какое-то pojo. Я хочу использовать только те значения, которые определены в кандидатаDoc. Но меня смущают круглые скобки, похоже, не получается заставить работать «return» или оператор if. Не могли бы вы указать мне правильное направление - не боюсь читать документацию.
terary
1
@cameck: спасибо, пост CW, не стесняйтесь редактировать.
georg
38

Новое Object.fromEntries, от ECMAScript 2019, упрощает преобразование значений из массива в ключи в объекте, как показано ниже.

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

console.log(obj)

Абдеррахман ТАХРИ ДЖУТИ
источник
21

в js с функцией уменьшения es6 для массива я делаю это так

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
источник
3
еще короче:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
exebook 04
5
var keys = ['key1', 'key2', 'key3']

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

Это произведет

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }
Алок Сингх Махор
источник
0

Я обнаружил, что вы можете просто использовать его Object.assign()напрямую с оператором распространения. Нет необходимости вводить дополнительную сложность с помощью функции reduceили map.

Просто делай Object.assign(...yourArray, {}) и вы получите желаемый результат. Если вы вместо этого хотите объединить свой массив объектов в другой объект, вы также можете вызвать, Object.assign(...yourArray, yourObject)и он также будет работать нормально.

Вы также можете использовать этот же метод для объединения двух массивов в один объект, даже если один из массивов не содержит объектов, а содержит только примитивные значения - однако, если вы это сделаете, вам необходимо убедиться, что хотя бы один из массивов содержит только объекты как примитив по умолчанию будет использовать свой индекс как key , поэтому вы получите ошибку, если будет дублированный ключ.

Однако для целей OP нет риска таких ошибок, так как он сливается с пустым объектом, что является наиболее безопасным способом.

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 }
Осмунд Берге Эндресен
источник
-4

вы можете использовать:

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

введите описание изображения здесь

jilykate
источник
3
Не то, что я хочу !!
Хуссейн Дехгамвала