0

How do I get a new array from a specific array?

I don't known how to handle an Array like this:

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}
  ...
]

"I want this result: from each item with the same name, pick biggest age value"

let arr2 = [
  {name: 'a', age: 3},
  {name: 'b', age: 3},
  {name: 'c', age: 2} 
  ...
]
2
  • 1
    const arr2 = arr1.filter( a => a.age === Math.max( ...arr1.filter( b => b.name === a.name ).map( ({ age }) => age ) ) ); Commented Jul 1, 2019 at 23:47
  • I think that's what you want, but I'm on mobile so I can't post an answer with code easily. Commented Jul 1, 2019 at 23:48

6 Answers 6

3

Just use filter to select all items with the highest age for their 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; }

Sign up to request clarification or add additional context in comments.

9 Comments

Much cleaner than mine... +1 :-D
Nice trick with the console snippet btw, I wasn't aware you could do that!
Yeah - that just lets the console output become bigger if it's required
That doesn't answer his question. He wants the biggest number. It isn't necessarily 3.
Better @BillyHudson?
|
2

You can use a combination of reduce and 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)

Comments

0

Extracted from this answer: How to filter object array based on attributes?

You can use the Array.prototype.filter method:

let arr2 = arr1.filter(function (obj) {
  return obj.age === 3;
});

4 Comments

sorry! this not my want, arr1 just a stucture like this, I have edit my new question!
@EVDS - you need to expand further in your question. Both posted answers will filter the array and return a new array based on the specified filter
@BenCarey what happens to age === 2 || age === 1 as the higest of it key?(name)
@BenCarey Sorry about that.
0

This is a more beautiful solution:

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)

Blockquote

Comments

0

my solution:

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)

Comments

-1

I didn't notice you update the question. This is not the most pro code.

  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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.