Как получить новый массив из определенного массива - PullRequest
0 голосов
/ 02 июля 2019

Как мне получить новый массив из определенного массива?

Я не знаю, как обращаться с таким массивом:

let arr1 = [
  {name: 'a', age: 1},
  {name: 'a', age: 2},
  {name: 'a', age: 3},
  {name: 'b', age: 1},
  {name: 'b', age: 2}
  {name: 'b', age: 3}
  {name: 'c', age: 1}
  {name: 'c', age: 2}
  ...
]

«Я хочу этот результат: из каждого элемента с одинаковым name выберите наибольшее значение age»

let arr2 = [
  {name: 'a', age: 3},
  {name: 'b', age: 3},
  {name: 'c', age: 2} 
  ...
]

Ответы [ 6 ]

3 голосов
/ 02 июля 2019

Просто используйте filter, чтобы выбрать все элементы с самым высоким age для их name.

let arr1 = [{name:'a',age:1},{name:'a',age:2},{name:'a',age:3},{name:'b',age:1},{name:'b',age:2},{name:'b',age:3}];

const biggest = arr1.reduce((a, { name, age }) => {
  a[name] = a[name] || age;
  age > a[name] ? a[name] = age : a[name];
  return a;
}, {});

let arr2 = arr1.filter(({ name, age }) => biggest[name] == age);

console.log(arr2);
.as-console-wrapper { max-height: 100% !important; top: auto; }
2 голосов
/ 02 июля 2019

Вы можете использовать комбинацию reduce и Object.values

 const arr1 = [
  {name: 'a', age: 1},
  {name: 'a', age: 2},
  {name: 'a', age: 3},
  {name: 'b', age: 1},
  {name: 'b', age: 2},
  {name: 'b', age: 3},
  {name: 'c', age: 1},
  {name: 'c', age: 2},
]

const maxNames = arr1.reduce((maxNamesObject, item) => {
  const { name, age } = item
  const maxItem = maxNamesObject[name]
  if (!maxItem || age > maxItem.age) {
    maxNamesObject[name] = item
  }
  return maxNamesObject
}, {})

const output = Object.values(maxNames)

console.log(output)
0 голосов
/ 02 июля 2019

мое решение:

const arr1 = [
  {name: 'a', age: 1},
  {name: 'a', age: 2},
  {name: 'a', age: 3},
  {name: 'b', age: 1},
  {name: 'b', age: 2},
  {name: 'b', age: 3},
  {name: 'c', age: 1},
  {name: 'c', age: 2},
]

let arr2 = arr1.reduce((acc, item) => {      
  let objectExists = acc.find(e => e.name === item.name)
  if (!objectExists) acc.push(item)
  else if (objectExists.age < item.age) {
      acc[acc.indexOf(objectExists)].age = item.age
  }
  return acc
}, [])

console.log(arr2)
0 голосов
/ 02 июля 2019

Это более красивое решение:

let arr1 = [
  {name: 'a', age: 1},
  {name: 'a', age: 2},
  {name: 'a', age: 3},
  {name: 'b', age: 1},
  {name: 'b', age: 2},
  {name: 'b', age: 3},
  {name: 'c', age: 1},
  {name: 'c', age: 2},
]

arr2 = Array.from(new Set(arr1.map(e => e.name))).map(e => { 
    return {
        name: e,
        age: Math.max(...arr1.filter(ee => ee.name == e).map(ee => ee.age))
    }
})

console.log(arr2)

Цитата

0 голосов
/ 02 июля 2019

Я не заметил, что вы обновили вопрос. Это не самый профессиональный код.

  let arr1 = [
  {name: 'a', age: 1}, {name: 'a', age: 2}, {name: 'a', age: 3},
  {name: 'b', age: 1}, {name: 'b', age: 2}, {name: 'b', age: 3},
  {name: 'c', age: 1}, {name: 'c', age: 2} ];

  let names = [];
  let output = [];

  for(obj of arr1){
   if (!names.includes(obj.name)) names.push(obj.name);
  }

  for(obj of names){
    let current = arr1.filter(x => x.name === obj)
                      .reduce((a,b) => a.age > b.age ? a : b);

    output.push(current);
  }

    console.log(output);
0 голосов
/ 02 июля 2019

Извлечено из этого ответа: Как отфильтровать массив объектов по атрибутам?

Вы можете использовать метод Array.prototype.filter:

let arr2 = arr1.filter(function (obj) {
  return obj.age === 3;
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...