# arr.rank()

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [objects](https://lochiwei.gitbook.io/web/js/val/obj) ⟩ [Array](https://lochiwei.gitbook.io/web/js/val/builtin/arr) ⟩ [methods](https://lochiwei.gitbook.io/web/js/val/builtin/arr/method) ⟩ rank()

{% tabs %}
{% tab title="💾 程式" %}
:floppy\_disk: replit: [arr.rank()](https://replit.com/@pegasusroe/arrrank#index.js)

```javascript
// 🔸 arr.rank()
Array.prototype.rank = function(compare, consecutiveRanks=true, rankPropertyName='rank'){

  const sorted = this
      .slice()            // copy the array
      .sort(compare);     // sort array of objects (in place)
    
  let current;            // object keeping the current rank

  // 🧨 Note：
  // - indices (keys) of array.entries() are "integer-based"
  // - indices (keys) of Object.entries(array) are "string-based"❗❗❗
  for(const [i, obj] of sorted.entries()){  

    // if not the same, generate new rank
    if (!current || compare(current, obj) !== 0) {
      obj[rankPropertyName] = (
          !consecutiveRanks ? i + 1 :        // ranks may have "gaps"
          !current          ?     1 :        // first rank
          current[rankPropertyName] + 1      // consecutive ranks
      );
      current = obj;
    }
        
    // if the same, use the current rank.
    else {
      obj[rankPropertyName] = current[rankPropertyName];
    }

  }

  return sorted;
};
```

💈範例：

```javascript
const players = [
    { nickname: "Bob"  , score: 100 },
    { nickname: "Amy"  , score: 200 },
    { nickname: "Grant", score: 300 },
    { nickname: "Steve", score: 200 },
    { nickname: "Joe"  , score: 500 },
];

console.log(players.rank((a,b) => b.score - a.score));
// [
//   { nickname: 'Joe'  , score: 500, rank: 1 },
//   { nickname: 'Grant', score: 300, rank: 2 },
//   { nickname: 'Amy'  , score: 200, rank: 3 },
//   { nickname: 'Steve', score: 200, rank: 3 },
//   { nickname: 'Bob'  , score: 100, rank: 4 }    // ⭐️ consecutive rank
// ]

console.log(players.rank((a,b) => b.score - a.score, false));
// [
//   { nickname: 'Joe'  , score: 500, rank: 1 },
//   { nickname: 'Grant', score: 300, rank: 2 },
//   { nickname: 'Amy'  , score: 200, rank: 3 },
//   { nickname: 'Steve', score: 200, rank: 3 },
//   { nickname: 'Bob'  , score: 100, rank: 5 }    // ⭐️ rank 4 is skipped.
// ]

console.log(players);
// [
//   { nickname: 'Bob'  , score: 100, rank: 5 },    // in original order
//   { nickname: 'Amy'  , score: 200, rank: 3 },
//   { nickname: 'Grant', score: 300, rank: 2 },
//   { nickname: 'Steve', score: 200, rank: 3 },
//   { nickname: 'Joe'  , score: 500, rank: 1 }
// ]
```

{% endtab %}

{% tab title="⬇️ 應用" %}

* [guo-zhong-cheng-ji-yi-lan-biao](https://lochiwei.gitbook.io/web/appendix/gas/projects/guo-zhong-cheng-ji-yi-lan-biao "mention") - 用於計算<mark style="color:yellow;">**班排**</mark>、<mark style="color:yellow;">**校排**</mark>。
  {% endtab %}

{% tab title="🗣 討論" %}

* [How to rank objects by property?](https://stackoverflow.com/questions/35737274/how-to-rank-objects-by-property)
  {% endtab %}

{% tab title="👥 相關" %}

* [arr.entries](https://lochiwei.gitbook.io/web/js/val/builtin/arr/method/arr.entries "mention")
  {% endtab %}
  {% endtabs %}
