Превратить массив объектов в объект - PullRequest
3 голосов
/ 04 июня 2019

У меня есть массив ветвей, который выглядит примерно так:

let branches = [
  {
    id: 21,
    name: "Branch 1",
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  {
    id: 22,
    name "Branch 2"
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  // .. etc
]

Но я бы хотел превратить его в объект с именем в качестве ключа для каждого.

Желаемый вывод:

branches = {
  "Branch 1": {
    id: 21,
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  "Branch 2": {
    id: 22,
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  }
}

Попытка:

let newBranches = branches.map(branch => (
  {
    [branch.name]: {
      id: branch.id,
      days: branch.opening_times
    }
  }
));
console.log(newBranches)

Но, конечно, отображение дает мне вывод массива:

[
  0: {Branch 1: {…}}
  1: {Branch 2: {…}}
]

Может ли кто-нибудь помочь мне указать мне правильнонаправление для получения нового объекта с ключом name в качестве самого объекта?

Ответы [ 7 ]

6 голосов
/ 04 июня 2019

С простой reduce() операцией и деструктуризацией объекта:

const branches = [{
    id: 21,
    name: "Branch 1",
    opening_times: []
  },
  {
    id: 22,
    name: "Branch 2",
    opening_times: []
  }
];

const result = branches.reduce((a, {name, ...v}) => (a[name] = v, a), {});

console.log(result);
6 голосов
/ 04 июня 2019

Я бы просто использовал простой цикл for-of.Вы получите reduce ответов, но все, что reduce делает, это добавляет сложность.

const result = {};
for (const {name, id, opening_times} of branches) {
  result[name] = {id, opening_times};
}

Live Пример:

let branches = [
  {
    id: 21,
    name: "Branch 1",
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  {
    id: 22,
    name: "Branch 2",
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  // .. etc
];
const result = {};
for (const {name, id, opening_times} of branches) {
  result[name] = {id, opening_times};
}
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}

Добавление в Код предложения маньяка об использовании отдыха:

const result = {};
for (const {name, ...entry} of branches) {
  result[name] = entry;
}

Live Пример:

let branches = [
  {
    id: 21,
    name: "Branch 1",
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  {
    id: 22,
    name: "Branch 2",
    opening_times: [ {}, {}, {} ] // Array of objects (Monday, Tuesday etc)
  },
  // .. etc
];
const result = {};
for (const {name, ...entry} of branches) {
  result[name] = entry;
}
console.log(result);
.as-console-wrapper {
    max-height: 100% !important;
}

Они немного отличаются тем, что первый явно использует только id и opening_times в результате, ноВ остальных версиях используются все свойства, кроме name.И, конечно, есть разница в удобочитаемости (явная и неявная), но есть места, где я бы использовал каждый из них.

4 голосов
/ 04 июня 2019

В проекте ES 2019 содержится Object.fromEntries для этой конкретной цели:

result = Object.fromEntries(branches.map(({name,...rest}) => [name, rest]))

Это уже реализовано в большинстве браузеров, но полифилл легко:

Object.fromEntries = iter =>
    Object.assign({},
        ...[...iter].map(
            ([k, v]) => ({[k]: v})
        ));
4 голосов
/ 04 июня 2019

Вы можете назначить весь объект, распространяя новый объект с требуемым ключом name и остальной частью объекта.

let branches = [{ id: 21, name: "Branch 1", opening_times: [{}, {}, {}] }, { id: 22, name: "Branch 2", opening_times: [{}, {}, {}] }],
    newBranches = Object.assign({}, ...branches.map(({ name, ...o }) => ({ [name]: o })));

console.log(newBranches);
.as-console-wrapper { max-height: 100% !important; top: 0; }

С (в ближайшее время) Object.fromEntries

let branches = [{ id: 21, name: "Branch 1", opening_times: [{}, {}, {}] }, { id: 22, name: "Branch 2", opening_times: [{}, {}, {}] }],
    newBranches = Object.fromEntries(branches.map(({ name, ...o }) => [name, o]));

console.log(newBranches);
.as-console-wrapper { max-height: 100% !important; top: 0; }
2 голосов
/ 04 июня 2019

Вы можете использовать reduce.

let branches = [{id:21,name:"Branch 1",opening_times:[{},{},{}]},{id:22,name:"Branch 2" ,opening_times:[{},{},{}]}];
const res = branches.reduce((acc, { name, ...rest }) => (acc[name] = { ...rest }, acc), {});
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }

Синтаксис ES5:

var branches = [{id:21,name:"Branch 1",opening_times:[{},{},{}]},{id:22,name:"Branch 2" ,opening_times:[{},{},{}]}];
var res = branches.reduce(function(acc, curr) {
  acc[curr.name] = { id: curr.id, opening_times: curr.opening_times };
  return acc;
}, {});
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
1 голос
/ 04 июня 2019

Вы можете попробовать это (ES6)

Object.assign({}, ...array.map(item => ({ [item.name]: item })));
1 голос
/ 04 июня 2019

let branches = [{
    id: 21,
    name: "Branch 1",
    opening_times: [{}, {}, {}] // Array of objects (Monday, Tuesday etc)
  },
  {
    id: 22,
    name: "Branch 2",
    opening_times: [{}, {}, {}] // Array of objects (Monday, Tuesday etc)
  }
]

let newBranches = {};

branches.forEach((el) => {
  newBranches[el.name] = {
    id: el.id,
    opening_times: el.opening_times
  };
});

console.log(newBranches)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...