Создание нового массива объектов javascript с уникальными значениями на основе другого массива объектов

#javascript #arrays

#javascript #массивы

Вопрос:

Предположим, что у меня есть следующий массив объектов:

 const contents = [
   {
       "id": 1,
       "category": ["cat1", "cat2"],
       "subcategory": ["subcat1"],
       "other": "lorem ipsum"
   },
   {
       "id": 2,
       "category": ["cat2"],
       "subcategory": ["subcat2"],
       "other": "lorem ipsum"
   },
   {
       "id": 3,
       "category": ["cat3"],
       "subcategory": ["subcat1", "subcat2"],
       "other": "lorem ipsum"
   }
]
  

Мне нужно сделать две вещи для приведенного выше массива. Первый заключается в создании массива с уникальным значением категории. Мне удалось сделать это с помощью следующего кода:

 let categories = contents.reduce(
   (arr, ele) => (
       [].push.apply(
          arr, ele.category.filter(v => arr.indexOf(v) == -1)
       ), arr), []
);
  

Второй — создание уникальной комбинации категории и подкатегории. Например, он выводит следующее:

  [
    {
        "category": "cat1",
        "subcategory": "subcat1"
    },
    {
        "category": "cat2",
        "subcategory": "subcat1"
    },
    {
        "category": "cat2",
        "subcategory": "subcat2"
    },
    {
        "category": "cat3",
        "subcategory": "subcat1"
    },
    {
        "category": "cat3",
        "subcategory": "subcat2"
    }
]
  

Есть какой-нибудь эффективный способ создать уникальную комбинацию категории и подкатегории?

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

1. пожалуйста, добавьте желаемый результат.

2. вы можете попробовать метод фильтрации.

Ответ №1:

Вы могли бы использовать Array#flatMap вложенное отображение.

 const contents = [{ id: 1, category: ["cat1", "cat2"], subcategory: ["subcat1"], other: "lorem ipsum" }, { id: 2, category: ["cat2"], subcategory: ["subcat2"], other: "lorem ipsum" }, { id: 3, category: ["cat3"], subcategory: ["subcat1", "subcat2"], other: "lorem ipsum" }],
    result = contents.flatMap(({ category, subcategory }) =>
        category.flatMap(category =>
            subcategory.map(subcategory => ({ category, subcategory }))
        )
    );

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

Ответ №2:

У вас может быть список пар категория-подкатегория, отфильтруйте уникальные пары, а затем сопоставьте с ожидаемым результатом

 const contents = [
  {
    id: 1,
    category: ['cat1', 'cat2'],
    subcategory: ['subcat1'],
    other: 'lorem ipsum'
  },
  {
    id: 2,
    category: ['cat2'],
    subcategory: ['subcat1', 'subcat2'],
    other: 'lorem ipsum'
  },
  {
    id: 3,
    category: ['cat3'],
    subcategory: ['subcat1', 'subcat2'],
    other: 'lorem ipsum'
  }
]

const res = contents
  .flatMap(content => {
    const catSubcat = []
    for (const cat of content.category) {
      for (const subcat of content.subcategory) {
        catSubcat.push([cat, subcat])
      }
    }
    return catSubcat
  })
  .reduce(
    (acc, el) =>
      acc.find(aEl => aEl[0] === el[0] amp;amp; aEl[1] === el[1])
        ? acc
        : [...acc, el],
    []
  )
  .map(([category, subcategory]) => ({ category, subcategory }))

console.log(res)  

Ответ №3:

Вы можете получить комбинацию элементов, используя getCombo() функцию.

Затем каждый объект комбинации строится и проверяется с помощью Set , если не в Set , он добавляется в Set и объект в массиве аккумуляторов:

 var contents = [{ id: 1, category: ["cat1", "cat2"], subcategory: ["subcat1"], other: "lorem ipsum" }, { id: 2, category: ["cat2"], subcategory: ["subcat2"], other: "lorem ipsum" }, { id: 3, category: ["cat3"], subcategory: ["subcat1", "subcat2"], other: "lorem ipsum" }];

function getUniqueCombo(contents) {
  return contents.reduce((acc, {
    category,
    subcategory
  }) => {
    const combo = getCombo(category, subcategory);
    combo.forEach(c => {
      const u = JSON.stringify(c);
      if (!acc.unique.has(u)) {
        acc.unique.add(u);
        acc.comb.push(c);
      }
    });

    return acc;
  }, {
    comb: [],
    unique: new Set()
  }).comb;

}

function getCombo(arrOne, arrTwo) {
  return arrOne.flatMap(a => arrTwo.map(b => ({
    category: a,
    subcategory: b
  })));
}

console.log(getUniqueCombo(contents));