Javascript ES6 Сопоставить массив объектов в Set или отфильтровать по отдельному свойству - PullRequest
0 голосов
/ 01 мая 2020

У меня есть массив объектов со свойством name и age, я хотел бы отфильтровать коллекцию разных возрастов среди массива, чтобы я мог сделать что-то вроде

function distinctAges() {
    const guests = [
          {name: 'Kiley', age: 24}, 
          {name: 'Tom', age: 36}, 
          {name: 'Jason', age: 67},
          {name: 'Mike', age: 24},
          ...];

    let ageSet = new Set();
    guests.foreach(g => ageSet.add(g.age));
    return ageSet;
}

Есть ли в любом случае не использующий Set тип данных, как Distinct операция? Если используется Set, есть ли в любом случае записать преобразование в одну строку?

Ответы [ 3 ]

3 голосов
/ 01 мая 2020

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

const distinctBy = (prop, arr) => [...new Set(arr.map(o => o[prop]))]

const guests = [{"name":"Kiley","age":24},{"name":"Tom","age":36},{"name":"Jason","age":67},{"name":"Mike","age":24}]

const result = distinctBy('age', guests)

console.log(result)
0 голосов
/ 01 мая 2020

На самом деле вы также можете просто использовать .reduce

      const guests = [
          {name: 'Kiley', age: 24}, 
          {name: 'Tom', age: 36}, 
          {name: 'Jason', age: 67},
          {name: 'Mike', age: 24}]
      
    console.log(guests.reduce((acc, rec) => acc.includes(rec.age) ? acc : [...acc, rec.age], []))

или с Set в одну строку:

      const guests = [
          {name: 'Kiley', age: 24}, 
          {name: 'Tom', age: 36}, 
          {name: 'Jason', age: 67},
          {name: 'Mike', age: 24}]
          
console.log([...new Set(guests.map(it => it.age))])
0 голосов
/ 01 мая 2020

Есть много способов сделать это - вопрос «как определить уникальность», который часто зависит от проблемной области.

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

let seen={};
let ageList=guests.filter((obj) => { 
  let ret = !seen[obj.age];
  seen[obj.age] = true; 
  return ret;
}).map((obj) => obj.age);
console.log(ageList);

Этот код устанавливает свойство в seen с тем же именем как ваш возраст во время функции фильтра. Если он не был установлен, он возвращает true, так что эта запись будет частью фильтруемого массива. Затем я применяю функцию map, которая отображает гостевые объекты для возрастов. В результате получается массив, содержащий все уникальные возрасты.

Одной из оптимизаций может быть использование запасного массива вместо объекта для определения уникальности, зная (предполагая), что все возрасты - это числа, и они имеют тенденцию быть совсем маленький - просто измените seen={} на seen=[] в приведенном выше примере.

Конечно, Кнут будет указывать, что преждевременная оптимизация является root всего зла - и я хотел бы отметить, что если вы заботитесь об оптимизации, вам также нужно измерить ....

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