Мне нужно объединить все объекты из элемента массива в один новый массив объектов

#javascript #arrays #reactjs #javascript-objects

Вопрос:

У меня есть вложенный массив, который имеет свойство под названием «параметры». Свойство options представляет собой массив объектов, и теперь каждый объект имеет свои собственные поля свойств, которые также являются массивом объектов.

Поэтому из каждой опции в массиве опций мне нужно получить поля опций и поместить их все в один новый массив.

Я опубликую изображение того, как выглядит мой массив, так как может быть проще понять, как он выглядит. Вот изображение массива.

Теперь я попытался сопоставить их все, а затем получить поля, но по-моему, он возвращает массив, но с каждым объектом fields, но я хочу, чтобы он возвращался, так как каждое поле внутри полей должно быть новым свойством массива.

 const obj = {
  key: 'clothes',
  label: 'Clothes',
  options: [
    {
      key: 'base-layers',
      label: 'base-layers',
      fields: [{ key: 'brand', label: 'brand' }, { key: 'size', label: 'Size' }],
    },
    {
      key: 'front-layers',
      label: 'front-layers',
      fields: [{ key: 'gender', label: 'Gender' }, { key: 'condition', label: 'Condition' }],
    },
  ],
};

const getFields = obj.options.map(a => a.map(f => f.fields));

const final = getFields.reduce((r, c) => Object.assign(r, c), {}));
 

Таким образом, каждое поле внутри объекта fields должно быть его собственным свойством в новом массиве объектов.

Я бы действительно оценил помощь!

Комментарии:

1. каким должен быть ваш ожидаемый результат? Пожалуйста, добавьте сам код?

Ответ №1:

Вы можете использовать одну функцию сокращения для перебора каждого параметра и объединения коллекции полей.

 const obj = {
  key: 'clothes',
  label: 'Clothes',
  options: [
    {
      key: 'base-layers',
      label: 'base-layers',
      fields: [{ key: 'brand', label: 'brand' }, { key: 'size', label: 'Size' }, { key: 'condition', label: 'Condition' }],
    },
    {
      key: 'front-layers',
      label: 'front-layers',
      fields: [{ key: 'gender', label: 'Gender' }, { key: 'condition', label: 'Condition' }],
    },
  ],
};

const allFields = obj.options.reduce((fields, option) => [...fields, ...option.fields], []);

console.log(allFields);


// Combine all fields without duplications (not optimized)

const allFieldsUnique = obj.options.reduce((fields, option) => {
  return [...fields, ...option.fields.filter(a => !fields.some(b => b.key === a.key))];
}, []);

console.log(allFieldsUnique); 

Комментарии:

1. Я отмечу это как ответ, работает как заклинание! Спасибо! Не могли бы вы помочь мне в том, как я могу сделать так, чтобы в этом новом массиве были только уникальные объекты, поэтому, если внутри есть два элемента с ключом «бренд», как я могу сохранить только один и так далее?

2. Мило! Я добавил второй пример, который отфильтровывает повторяющиеся поля.

3. Большое спасибо, Крис!

Ответ №2:

Используйте Array.flatMap() для получения массива, выбирая поля из каждого параметра.

Если вам нужен объект, сопоставьте поля с массивом [key, value] пар и преобразуйте в объект с помощью Object.fromEntries() :

 const obj = {"key":"clothes","label":"Clothes","options":[{"key":"base-layers","label":"base-layers","fields":[{"key":"brand","label":"Brand"},{"key":"size","label":"Size"}]},{"key":"front-layers","label":"front-layers","fields":[{"key":"gender","label":"Gender"},{"key":"condition","label":"Condition"}]}]};

const arr = obj.options.flatMap(option => option.fields)

console.log(arr);

const object = Object.fromEntries(obj.options.flatMap(option =>
  option.fields.map(({ key, label }) => [key, label])
));

console.log(object); 

Комментарии:

1. Спасибо за помощь, ваше решение кажется действительно хорошим, даже если я выбрал верхнее, так как оно было первым. Еще раз спасибо!!

2. Без уникального фильтра, я думаю, мне нравится flatMap больше, так как он намного короче, чем reduce .