Javascript Объединение элементов в объекте Array - PullRequest
2 голосов
/ 02 марта 2020

Я обнаружил _.reduce, однако он хранит только 1 часть информации. Какой вариант следует использовать для объединения как информации?

[
  {
    fruit: 'apple',
    'color': 'red'
  },
  {
    fruit: 'apple',
    'color': 'green'
  },
  {
    fruit: 'pear',
    'color': 'yellow'
  },
  {
    fruit: 'pear',
    'color': 'green'
  }
]

Мой желаемый результат будет:

var items = [
  {
    fruit: 'apple',
    'color': 'red', 'green'
  },
  {
    fruit: 'pear',
    'color': 'green', 'yellow'
  }
]

Текущий код, который я использую NodeJS:

 let result = Object.values(json.reduce((c, {fruit,...r}) => {
   c[fruit] = c[fruit] || {fruit};
   c[fruit] = Object.assign(c[fruit], r);
   return c;
 }, {}));

Ответы [ 3 ]

2 голосов
/ 02 марта 2020

Это подход, который выполняется во времени O (n) вместо O (n ^ 2):

const arr = [
  {
    fruit: 'apple',
    'color': 'red',
  },
  {
    fruit: 'apple',
    'color': 'green',
  },
  {
    fruit: 'pear',
    'color': 'yellow',
  },
  {
    fruit: 'pear',
    'color': 'green',
  },
];
const map = arr.reduce((acc, o) => {
  if (acc[o.fruit]) {
    acc[o.fruit].push(o.color);
  } else {
    acc[o.fruit] = [o.color];
  }
  return acc;
}, {});
const result = Object.keys(map).map(k => ({ fruit: k, colors: map[k] }));
console.log(result);
return result;

Обратите внимание, что, как отмечено в ответе Ника, разница не будет иметь значения для небольшого массива, но если массив большой или само преобразование заключено в al oop, это может иметь значение.

1 голос
/ 02 марта 2020

Для этого вы можете использовать метод Array reduce. Предполагая, что ваш массив не очень длинный, использование метода find на каждой итерации не должно быть слишком дорогим. Если это супер длинный массив, вы можете вместо этого выбрать промежуточный объект, который имеет sh эффективность таблицы. Вероятно, не обязательно, однако.

const arr = [
  {
    fruit: 'apple',
    'color': 'red'
  },
  {
    fruit: 'apple',
    'color': 'green'
  },
  {
    fruit: 'pear',
    'color': 'yellow'
  },
  {
    fruit: 'pear',
    'color': 'green'
  }
];

const combined = arr.reduce((acc, el) => {
  const fruit = acc.find(item => item.fruit === el.fruit);
  if (fruit) {
    fruit.colors.push(el.color)
  } else {
    acc.push({ fruit: el.fruit, colors: [el.color] });
  }
  return acc;
}, []);

console.log(combined);
0 голосов
/ 02 марта 2020

Используйте простые forEach и создайте объект из уникальных ключей и получите значения, используя Object.values.

const data = [
  {
    fruit: "apple",
    color: "red"
  },
  {
    fruit: "apple",
    color: "green"
  },
  {
    fruit: "pear",
    color: "yellow"
  },
  {
    fruit: "pear",
    color: "green"
  }
];

const res = {};

data.forEach(
  item =>
    (res[item.fruit] =
      item.fruit in res
        ? { ...res[item.fruit], color: [...res[item.fruit].color, item.color] }
        : { fruit: item.fruit, color: [item.color] })
);

const output = Object.values(res);

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