Объединить сам массив в другой массив с тем же ключом в JavaScript - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь объединить сам массив и преобразовать его в более значимый массив

array = [
{item: 'pen', madeIn: 'US', color: 'blue'},
{item: 'pen', madeIn: 'US', color: 'white'},
{item: 'pen', madeIn: 'China', color: 'red'},
{item: 'pen', madeIn: 'China', color: 'white'}
]

выходной массив, который я хочу создать:

outputArray = [
{item: 'pen', madeIn: 'US', color: ['blue', 'white']},
{item: 'pen', madeIn: 'China', color: ['red', 'white']}
];

Я пыталсяно не повезло, единственное решение, о котором я могу подумать в данный момент, это использование временной переменной для хранения элемента и значения madeIn.и запустить еще один цикл для сравнения элемента и madeIn, а затем добавить цвет в массив.Существует несколько циклов для решения этой проблемы.

Я имею в виду, что она работает, но определенно не является оптимальным решением.любой другой идеал будет приветствоваться.Спасибо.

Ответы [ 3 ]

4 голосов
/ 16 апреля 2019

Уменьшите массив до объекта, используя свойства item и madeIn для создания ключа.Для каждого объекта проверьте, существует ли ключ, и, если нет, создайте новый объект для ключа со свойством color в виде пустого массива.Нажмите color каждого объекта в массив.Используйте Object.values() для преобразования объекта в массив.

const array = [{"item":"pen","madeIn":"US","color":"blue"},{"item":"pen","madeIn":"US","color":"white"},{"item":"pen","madeIn":"China","color":"red"},{"item":"pen","madeIn":"China","color":"white"}]

const result = Object.values(
  array.reduce((r, o) => {
    const key = `${o.item}-${o.madeIn}`
    
    if(!r[key]) r[key] = { ...o, color: [] }
    
    r[key].color.push(o.color)
    
    return r;
  }, {})
)

console.log(result)
1 голос
/ 16 апреля 2019

Вот решение, которое использует Array.prototype.reduce() и деструктуризацию объекта:

const initialArray = [
  {item: 'pen', madeIn: 'US', color: 'blue'},
  {item: 'pen', madeIn: 'US', color: 'white'},
  {item: 'pen', madeIn: 'China', color: 'red'},
  {item: 'pen', madeIn: 'China', color: 'white'}
];

const finalArray = initialArray.reduce((accumulator, currentValue) => {
  const item = accumulator.find(x => x.item === currentValue.item && x.madeIn === currentValue.madeIn);
  if(item) {
    item.color.push(currentValue.color);
  }
  else {
    accumulator.push({...currentValue, color: [currentValue.color]});
  }
  return accumulator; 
}, []);

console.log(finalArray);

В отличие от других ответов, он не основан на «не столь уникальном» ключе и будет работать для любых данных.

1 голос
/ 16 апреля 2019

Использование reduce:

const array = [{ item: 'pen', madeIn: 'US', color: 'blue' }, { item: 'pen', madeIn: 'US', color: 'white' }, { item: 'pen', madeIn: 'China', color: 'red' }, { item: 'pen', madeIn: 'China', color: 'white' }];

const output = Object.values(array.reduce((acc, { item, madeIn, color}) => {
  acc[`${item}-${madeIn}`] = acc[`${item}-${madeIn}`] || { item, madeIn, color: [] };
  acc[`${item}-${madeIn}`].color.push(color);
  return acc;
}));

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