Junior Yono
Junior Yono

Reputation: 516

Javascript filter array by number value

I have an array like this

const allChampions = 
  [ { champion: 'Vayne', percentage:  33.33, role: 'top'     } 
  , { champion: 'Jinx',  percentage:   0,    role: 'jungle'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'mid'     } 
  , { champion: 'Jinx',  percentage: 100,    role: 'bottom'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'support' } 
  ] 

I want to filter out the array by checking for duplicate champions. If the champion is a duplicate, I want to remove the champion with the lowest percentage.

I've tried filtering the array into a new one using this:

let sortedChampions = [];
sortedChampionsWithDuplicates.map((x) =>
    sortedChampions.filter((a) => a.champion == x.champion && a.percentage >= x.percentage).length > 0 ? null : sortedChampions.push(x)
);

But this is what the end result ends up being:

[{"champion":"Vayne","percentage":33.33,"role":"top"},{"champion":"Jinx","percentage":0,"role":"jungle"},{"champion":"Jinx","percentage":100,"role":"bottom"}]

Upvotes: 1

Views: 116

Answers (2)

Mister Jojo
Mister Jojo

Reputation: 22265

you can do that...

const allChampions = 
  [ { champion: 'Vayne', percentage:  33.33, role: 'top'     } 
  , { champion: 'Jinx',  percentage:   0,    role: 'jungle'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'mid'     } 
  , { champion: 'Jinx',  percentage: 100,    role: 'bottom'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'support' } 
  ] 

for (let i=allChampions.length;i--;) 
  {
  let curr   = allChampions[i]
    , bigger = allChampions.find(x=>x.champion===curr.champion && x.percentage > curr.percentage)
  if (bigger) 
    allChampions.splice(i,1)
  }

console.log( allChampions )

OR, if you want to create a new array:

const allChampions = 
  [ { champion: 'Vayne', percentage:  33.33, role: 'top'     } 
  , { champion: 'Jinx',  percentage:   0,    role: 'jungle'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'mid'     } 
  , { champion: 'Jinx',  percentage: 100,    role: 'bottom'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'support' } 
  ] 

const sortedChampions =
  allChampions.filter( (c,_,t) =>
    !t.find( x => x.champion === c.champion 
               && x.percentage > c.percentage )
                     )
  
console.log( sortedChampions )

OR, if you doesn't want to use a find :

const allChampions = 
  [ { champion: 'Vayne', percentage:  33.33, role: 'top'     } 
  , { champion: 'Jinx',  percentage:   0,    role: 'jungle'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'mid'     } 
  , { champion: 'Jinx',  percentage: 100,    role: 'bottom'  } 
  , { champion: 'Vayne', percentage:   0,    role: 'support' } 
  ] 

const result = Object.values(allChampions.reduce((acc, curr) =>
  {
  if ((acc[curr.champion]?.percentage || -1) < curr.percentage ) 
    acc[curr.champion] = curr
  return acc
  }, {})) 

console.log( result )

Upvotes: 1

patrickmedaugh
patrickmedaugh

Reputation: 21

I'm assuming this is just a quick script for your own purposes, so something like this might work:

const removeDupes = allChampions.reduce((acc, champStats) => {
  if (acc[champStats.champion]) {
    acc[champStats.champion] = acc[champStats.champion].percentage > champStats.percentage ? acc[champStats.champion] : champStats
    return acc
  } else {
    acc[champStats.champion] = champStats
    return acc
  }
}, {})

console.log(Object.values(removeDupes))

Upvotes: 2

Related Questions