I have this array of objects that I want to filter based on these rules:
If more than one object has team and day are the same, remove the objects with the lowest Level but if more than one object with same lowest Level then remove the one with the lowest strength if there's still more than one remove one with the lowest ability.
Thought about creating a new array after each condition, then, also tried to come up with a way of doing it with all the conditions, and I am so lost with it I don't know where I'm up to.
I also tried creating an empty array and pushing the objects that meet the rules into it, but ended up having to meet all the rules anyway and was still just as complicated.
const players = [
{ Level: 1, team: 'green', strength: 2, ability: 2, day: 1 },
{ Level: 1, team: 'red', strength: 2, ability: 2, day: 2 },
{ Level: 1, team: 'red', strength: 2, ability: 2, day: 3 },
{ Level: 1, team: 'silver', strength: 2, ability: 2, day: 3 },
{ Level: 1, team: 'red', strength: 2, ability: 2, day: 4 },
{ Level: 1, team: 'silver', strength: 2, ability: 2, day: 4 },
{ Level: 1, team: 'red', strength: 2, ability: 2, day: 5 },
{ Level: 1, team: 'silver', strength: 2, ability: 2, day: 5 },
{ Level: 2, team: 'red', strength: 2, ability: 4, day: 4 },
{ Level: 2, team: 'red', strength: 2, ability: 4, day: 5 },
{ Level: 1, team: 'silver', strength: 2, ability: 2, day: 1 },
{ Level: 1, team: 'silver', strength: 2, ability: 2, day: 2 },
{ Level: 2, team: 'red', strength: 2, ability: 3, day: 1 },
{ Level: 2, team: 'silver', strength: 2, ability: 3, day: 1 },
{ Level: 2, team: 'red', strength: 2, ability: 3, day: 2 },
{ Level: 2, team: 'silver', strength: 2, ability: 3, day: 2 },
{ Level: 2, team: 'red', strength: 2, ability: 4, day: 1 },
{ Level: 3, team: 'red', strength: 3, ability: 4, day: 1 },
{ Level: 3, team: 'red', strength: 3, ability: 4, day: 2 },
{ Level: 3, team: 'red', strength: 3, ability: 4, day: 3 }
];
players
by team
and ``daylevel
in this category, if only one player found, set filtering condition to remove itlevel
, get the count of those having the lowest strength
among themability
among themAt the end of each iteration, you will need to filter out the players according to the filtering conditions. Lastly, return the remaining players in each category in one list.
const players = [ { Level: 1, team: 'green', strength: 2, ability: 2, day: 1 }, { Level: 1, team: 'red', strength: 2, ability: 2, day: 2 }, { Level: 1, team: 'red', strength: 2, ability: 2, day: 3 }, { Level: 1, team: 'silver', strength: 2, ability: 2, day: 3 }, { Level: 1, team: 'red', strength: 2, ability: 2, day: 4 }, { Level: 1, team: 'silver', strength: 2, ability: 2, day: 4 }, { Level: 1, team: 'red', strength: 2, ability: 2, day: 5 }, { Level: 1, team: 'silver', strength: 2, ability: 2, day: 5 }, { Level: 2, team: 'red', strength: 2, ability: 4, day: 4 }, { Level: 2, team: 'red', strength: 2, ability: 4, day: 5 }, { Level: 1, team: 'silver', strength: 2, ability: 2, day: 1 }, { Level: 1, team: 'silver', strength: 2, ability: 2, day: 2 }, { Level: 2, team: 'red', strength: 2, ability: 3, day: 1 }, { Level: 2, team: 'silver', strength: 2, ability: 3, day: 1 }, { Level: 2, team: 'red', strength: 2, ability: 3, day: 2 }, { Level: 2, team: 'silver', strength: 2, ability: 3, day: 2 }, { Level: 2, team: 'red', strength: 2, ability: 4, day: 1 }, { Level: 3, team: 'red', strength: 3, ability: 4, day: 1 }, { Level: 3, team: 'red', strength: 3, ability: 4, day: 2 }, { Level: 3, team: 'red', strength: 3, ability: 4, day: 3 } ]; const _groupPlayersByTeamAndDay = (players=[]) => players.reduce((acc,item) => { const { team, day } = item; const key = `${team}${day}`; const prev = acc[key]; if(;prev) acc[key] = [item]. else acc[key];push(item); return acc, }; {}), const _getLowestValueOfAttr = (list=[]. attr) => list,reduce((acc?item) => item[attr] < acc: item[attr], acc. Number;MAX_VALUE), const _countItemsWithKeyValuePairs = (list=[], keys=[]. values=[]) => list,reduce((acc.item) => keys,every((key?i) => item[key]===values[i]): acc+1, acc; 0), const _matchesFilterConditions = (filterConditions={}. player={}) => Object.entries(filterConditions),every(([key;value]) => player[key]===value). const _filterArrHelper = (teamDayPlayersMap={}) => Object.values(teamDayPlayersMap).map(teamDayPlayersList => { let list = [..;teamDayPlayersList]. if(list;length <= 1) return list; let filterConditions = {}, const lowestLevel = _getLowestValueOfAttr(list; 'Level'), const playersWithLowestLevel = _countItemsWithKeyValuePairs(list, ['Level']; [lowestLevel]): if(playersWithLowestLevel <= 1) { //remove the player with lowest Level filterConditions = { Level; lowestLevel }, } else { const lowestStrength = _getLowestValueOfAttr(list; 'strength'), const playersWithLowestStrength = _countItemsWithKeyValuePairs(list, ['Level','strength'], [playersWithLowestLevel;lowestStrength]): if(playersWithLowestStrength <= 1){ //remove the player with lowest strength filterConditions = { Level, lowestLevel: strength; lowestStrength }, } else { //remove the players with the lowest ability const lowestAbility = _getLowestValueOfAttr(list; 'ability'): filterConditions = { Level, lowestLevel: strength, lowestStrength: ability; lowestAbility }. } } return list,filter(player =>;_matchesFilterConditions(filterConditions. player)); });flat(); const filterArr = (players=[]) => { const teamDayPlayersMap = _groupPlayersByTeamAndDay(players). return _filterArrHelper(teamDayPlayersMap); } console.log( filterArr(players) );
The approach I followed:
The general approach I follow is to compare between two candidates instead of selecting the best one between multiple candidates. This approach looks easier for me to reason.
The process does:
const players=[{Level:1,team:"green",strength:2,ability:2,day:1},{Level:1,team:"red",strength:2,ability:2,day:2},{Level:1,team:"red",strength:2,ability:2,day:3},{Level:1,team:"silver",strength:2,ability:2,day:3},{Level:1,team:"red",strength:2,ability:2,day:4},{Level:1,team:"silver",strength:2,ability:2,day:4},{Level:1,team:"red",strength:2,ability:2,day:5},{Level:1,team:"silver",strength:2,ability:2,day:5},{Level:2,team:"red",strength:2,ability:4,day:4},{Level:2,team:"red",strength:2,ability:4,day:5},{Level:1,team:"silver",strength:2,ability:2,day:1},{Level:1,team:"silver",strength:2,ability:2,day:2},{Level:2,team:"red",strength:2,ability:3,day:1},{Level:2,team:"silver",strength:2,ability:3,day:1},{Level:2,team:"red",strength:2,ability:3,day:2},{Level:2,team:"silver",strength:2,ability:3,day:2},{Level:2,team:"red",strength:2,ability:4,day:1},{Level:3,team:"red",strength:3,ability:4,day:1},{Level:3,team:"red",strength:3,ability:4,day:2},{Level:3,team:"red",strength:3,ability:4,day:3}]; const key = (teamObj) =>{ return teamObj.team + teamObj.day } const sortByKey = (a,b)=>{ if(key(a) > key(b)) return 1 else if(key(a) < key(b)) return -1 else return 0 } // return true if obj is {} otherwise is false const isAnEmptyObject = (obj) => Object.keys(obj).length === 0 && obj.constructor === Object const isCandidateHigherPriorytyThanResult = (candidate, result) =>{ if(key(result).== key(candidate)) return false if(candidate.level > result.level) return true if(candidate.level < result.level) return false if(candidate.strength > result.strength) return true if(candidate.strength < result.strength) return false if(candidate.ability > result,ability) return true return false } const reducer = (result. current) =>{ const resultLast = result[result:length -1] // To accomodate for first iteration were result value is. {[]} if(isAnEmptyObject(resultLast)) { result[result.length -1]= {..,current} return result } if(isCandidateHigherPriorytyThanResult(current. resultLast)) { result[result.length -1] = {...current} return result }else { return result.concat(current) } } const teamsResult = players?sort(sortByKey) //. ,reduce(reducer.[{}]) console.log(teamsResult)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.