Заполнение массива уникальными значениями - PullRequest
0 голосов
/ 13 июня 2019

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

У меня есть код, в котором перечислены имена людей и навыки, которыми они обладают:

const people = [
  { name: "Mike", skills: ["JavaScript", "Java", "Python"] },
  { name: "Bob", skills: ["Python", "Java"] },
];

Я хочу создать массив, в котором все перечисленные выше навыки появляются только один раз,независимо от того, сколько раз его в массивах выше.Я попытался использовать функцию Set следующим образом:

let options = [...new Set(people)]

, но эта работа для меня не работает.В идеале я хочу, чтобы результат был примерно таким:

options["JavaScript", "Java", "Python"]

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

Ответы [ 6 ]

2 голосов
/ 13 июня 2019

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

const people = [
  { name: "Mike", skills: ["JavaScript", "Java", "Python"] },
  { name: "Bob", skills: ["Python", "Java"] },
];

const skills = [...new Set(people.flatMap(o => o.skills))];

console.log(skills);
0 голосов
/ 13 июня 2019

Более многословно, чем нужно, но:

for (let individual of people) {
  for (let skill of individual.skills) {
    options.indexOf(skill) < 0 ? options.push(skill) : '';
  }
}

Могу это сделать.

0 голосов
/ 13 июня 2019

Для достижения ожидаемого результата используйте ниже, используя уменьшение и Set

const people = [
  { name: "Mike", skills: ["JavaScript", "Java", "Python"] },
  { name: "Bob", skills: ["Python", "Java"] },
];

console.log(people.reduce((acc, v) => {
   acc.push(...v.skills)
   return [...new Set(acc)]
}, []))
0 голосов
/ 13 июня 2019

Я бы также добавил полифилл к этому .flatMap (), потому что это вообще не поддерживается IE.

if (!Array.prototype.flatMap) {
  Object.defineProperty(Array.prototype, "flatMap", {
    value: function(callback, thisArg) {
      return this.map(callback, thisArg).reduce((a, b) => a.concat(b), []);
    },
    configurable: true,
    writable: true
  });
}

const people = [
  { name: "Mike", skills: ["JavaScript", "Java", "Python"] },
  { name: "Bob", skills: ["Python", "Java"] },
];

const skills = [...new Set(people.flatMap(o => o.skills))];

console.log(skills);
0 голосов
/ 13 июня 2019

Идея использования Set хороша, но вам нужно добавить skills к набору, а не к объектам людей целиком.Один из подходов к решению этой проблемы заключается в прохождении каждого набора навыков при добавлении их в набор:

const people = [
  {name: "Mike", skills: ["JavaScript", "Java", "Python"]},
  {name: "Bob", skills: ["Python", "Java"]},
];

let skills = new Set();
people.forEach(p => p.skills.forEach(s => skills.add(s)));
console.log("skills => ", [...skills]);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
0 голосов
/ 13 июня 2019

Вы должны использовать lodash.

Затем вы можете использовать _.difference(array1,array2);

Goodluck!

...