I have array of players sorted by number of goals:
let players = [
{"name": "player1", "goals": "5"},
{"name": "player5", "goals": "4"},
{"name": "player2", "goals": "4"},
{"name": "player3", "goals": "2"},
{"name": "player4", "goals": "1"}
]
I want to show this data with the position in the table, like this:
- player1 - 5 goals
- player5 - 4 goals
- player2 - 4 goals
- player3 - 2 goals
- player4 - 1 goal
If two (or more players) have the same number of goals - they must have the same position in the table (in example - 2.), end next number in enumartion should be missed (no number 3. in this example).
How to add this type ,,position in order in array'' (i'm not sure that's good words to describe this)?
CodePudding user response:
I required something similar to this some time ago and came up with this:
function sortedRank(arr, childProp, asc) {
let prev, position = 0, ranking = 0;
return [...arr]
.sort((a, b) => asc ? a[childProp] - b[childProp] : b[childProp] - a[childProp])
.map((target, idx) => {
const obj = { target };
obj.indexRank = idx 1;
if (target[childProp] != prev) {
position = obj.rank = obj.indexRank;
ranking ;
prev = target[childProp];
} else {
obj.rank = position;
}
obj.altRank = ranking;
return obj
});
}
It returns 3 different ranking types together with the child object from the original array.
Where resultArr[0].rank
is the rank from 1-N, but skips equal rank numbers.
For example:
source = resultArr[index].rank
goals 5 = 1.
goals 4 = 2.
goals 4 = 2.
goals 3 = 4.
goals 1 = 5.
resultArr[0].altRank
doesn't skip ranking numbers.
source = resultArr[index].altRank
goals 5 = 1.
goals 4 = 2.
goals 4 = 2.
goals 3 = 3.
goals 1 = 4.
and indexRank is the position after sorting.
const list = [
{"name": "player1","goals": "5"},
{"name": "player5","goals": "4"},
{"name": "player2","goals": "4"},
{"name": "player3","goals": "2"},
{"name": "player4","goals": "1"}
];
function sortedRank(arr, childProp, ascending) {
let prev, position = 0,
ranking = 0;
return [...arr]
.sort((a, b) => ascending ? a[childProp] - b[childProp] : b[childProp] - a[childProp])
.map((target, idx) => {
const obj = { target };
obj.indexRank = idx 1;
if (target[childProp] != prev) {
position = obj.rank = obj.indexRank;
ranking ;
prev = target[childProp];
} else {
obj.rank = position;
}
obj.altRank = ranking;
return obj
});
}
sortedRank(list, 'goals').forEach(({ indexRank, rank, altRank, target }) => {
console.log(`idxRank: ${indexRank} rank: ${rank} alternative: ${altRank}`, target);
});
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You could use an ordered list element (<ol>
) to render that list, which automatically numbers the list items:
<ol>
<li v-for="player in players" :key="player.name">
{{ player.name }} - {{ player.goals }} goals
</li>
</ol>
CodePudding user response:
Try this:
const
player_obj = [
{ "name": "player1", "goals": "5" },
{ "name": "player5", "goals": "4" },
{ "name": "player2", "goals": "4" },
{ "name": "player3", "goals": "2" },
{ "name": "player4", "goals": "1" }
]
player_obj.sort((a, b) => a.goals - b.goals)
str = ''
for (let i = 0; i < player_obj.length; i ) {
const
player = player_obj[i]
str = `
<tr><td>${i 1}. ${player.name} - ${player.goal} goals</td></tr>
`
}
table.innerHTML = str
CodePudding user response:
You can do it like this:
const players=[ {"name": "player1", "goals": "5"},
{"name": "player5", "goals": "4"},
{"name": "player2", "goals": "4"},
{"name": "player3", "goals": "2"},
{"name": "player4", "goals": "1"}]
const playersSorted = players.sort((a, b)=> a.goals - b.goals);
//console.log(playersSorted)
let currentPosition = 1; let lastGoalsNbr =playersSorted[0].goals;
const playersPositioned = playersSorted.map(({name, goals})=> {
if(lastGoalsNbr !== goals ) currentPosition ;
lastGoalsNbr = goals;
return {name, goals, position:currentPosition}
}
)
console.log(playersPositioned)