Как добавить позицию по порядку в существующий массив в javascript / Vue.js ?

#javascript #vue.js

#javascript #vue.js

Вопрос:

У меня есть массив игроков, отсортированных по количеству голов:

  let players = [
  {"name": "player1", "goals": "5"},
  {"name": "player5", "goals": "4"},
  {"name": "player2", "goals": "4"},
  {"name": "player3", "goals": "2"},
  {"name": "player4", "goals": "1"}
]
 

Я хочу показать эти данные с указанием позиции в таблице, вот так:

  1. игрок1 — 5 голов
  2. игрок5 — 4 гола
  3. игрок2 — 4 гола
  4. игрок 3 — 2 гола
  5. игрок 4 — 1 гол

Если у двух (или более игроков) одинаковое количество голов — они должны занимать одинаковую позицию в таблице (в примере — 2.), Следующий номер в перечислении должен быть пропущен (в этом примере нет номера 3.).

Как добавить этот тип ,,положение по порядку в массиве» (я не уверен, что это хорошие слова для описания этого)?

Ответ №1:

Некоторое время назад мне требовалось что-то похожее на это, и я придумал это:

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

Он возвращает 3 разных типа ранжирования вместе с дочерним объектом из исходного массива.

Где resultArr[0].rank ранг от 1 до N, но пропускает равные номера ранга. Например:

 source  = resultArr[index].rank
goals 5 = 1.
goals 4 = 2.
goals 4 = 2.
goals 3 = 4.
goals 1 = 5.
 

resultArr[0].altRank не пропускает номера ранжирования.

 source  = resultArr[index].altRank
goals 5 = 1.
goals 4 = 2.
goals 4 = 2.
goals 3 = 3.
goals 1 = 4.
 

а indexRank — это позиция после сортировки.

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

Ответ №2:

Вы могли бы использовать элемент упорядоченного списка ( <ol> ) для отображения этого списка, который автоматически нумерует элементы списка:

 <ol>
  <li v-for="player in players" :key="player.name">
    {{ player.name }} - {{ player.goals }} goals
  </li>
</ol>
 

ДЕМОНСТРАЦИЯ

Ответ №3:

Попробуйте это:

 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
 

Ответ №4:

Вы можете сделать это следующим образом:

 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)