Как объединить все массивы объектного массива, чтобы получить уникальные значения? - PullRequest
0 голосов
/ 25 мая 2018

У меня есть такие данные:

const items = [
  { _id: '1', reference: ['abc'] },
  { _id: '2', reference: ['def'] },
  { _id: '3', reference: ['abc'] }
]

Длина items всегда различна.

Теперь мне нужно получить все уникальные ссылочные строки в одном массиве,Таким образом, результат должен быть

['abc', 'def']

, поскольку 'abc' является дубликатом.

Я пытался использовать цикл forEach():

const references = []
items.forEach(i => {
  references.concat(i.reference)
})

console.log(references)

Но references просто получает пустой результат массива.Также с этим я не позаботился о дубликатах ...


Я хотел бы использовать шаблон ES6.С этим я знаю, что могу использовать что-то вроде этого:

const array1 = ['abc']
const array2 = ['def']
const array3 = Array.from(new Set(array1.concat(array2)))

Но как я могу сделать это, используя цикл для получения каждого ссылочного массива каждого объекта элемента - даже если я не знаю, сколько объектов вмассив элементов?

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Если вы хотите сделать функциональный стиль (уменьшение карты), вы можете сделать это следующим образом

const items = [
  { _id: '1', reference: ['abc'] },
  { _id: '2', reference: ['def'] },
  { _id: '3', reference: ['abc'] }
]

// extract references and put them into a single array
const references = 
  items
    .map(x => x.reference)
    .reduce((prev, cur) => prev.concat(cur))
    
// put them in a set to dedupe
const set = new Set(references)

console.log(references)
console.log([...set])

Если вы хотите сделать меньше проходов по данным, а также избежать необходимости в Set, вы можете это сделать.

const items = [
  { _id: '1', reference: ['abc'] },
  { _id: '2', reference: ['def'] },
  { _id: '3', reference: ['abc'] }
]

const result = Object.keys(items.reduce((obj, {reference}) => {
  for (const ref of reference) {
    obj[ref] = true
  }
  return obj;
}, {}))

console.log(result)

Вы также можете обменять выразительность на производительность с полностью императивным подходом ниже.

const items = [
  { _id: '1', reference: ['abc'] },
  { _id: '2', reference: ['def'] },
  { _id: '3', reference: ['abc'] }
];

const occ = {};
const references = [];
for (let i = 0; i < items.length; ++i) {
  const refs = items[i].reference;
  for (let j = 0; j < refs.length; ++j) {
    const ref = refs[j];
    if (occ[ref] == null) {
      references.push(ref);
      occ[ref] = true;
    }
  }
}

console.log(references)
  
0 голосов
/ 25 мая 2018

Это похоже на другие решения здесь, но создает функцию многократного использования:

const uniqRefs = 
  items => [...items.reduce((s, i) => s.add(...i.reference), new Set())]


const items = [{"_id": "1", "reference": ["abc"]}, {"_id": "2", "reference": ["def"]}, {"_id": "3", "reference": ["abc"]}]
console.log(uniqRefs(items))
0 голосов
/ 25 мая 2018

Если вы хотите использовать наборы, вы можете использовать Set.add и синтаксис распространения :

const items = [
  { _id: '1', reference: ['abc'] },
  { _id: '2', reference: ['def'] },
  { _id: '3', reference: ['abc'] }
]

var references = new Set();
items.forEach(i => references.add(...i.reference))
console.log(Array.from(references))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...