Как определить уровень, исходя из заданного массива?

Как улучшить реализацию подсчета уровня пользователя на основе количества его заказов? Вот мой текущий код, но я чувствую, что его можно улучшить. У вас есть какие-либо предложения? 

```javascript
const LVLS = [
  {exp: 10, lv: 1},
  {exp: 25, lv: 2},
  {exp: 45, lv: 3},
  {exp: 70, lv: 4},
  {exp: 100, lv: 5},
];
const EXP = 47;
let lvl = 0;

LVLS.forEach((l) => {
  if(EXP >= l.exp) {
    lvl = l.lv;
  }
});

console.log(lvl);
```

Буду благодарен за любые рекомендации по улучшению этого кода!
  • 15 февраля 2024 г. 13:18
Ответы на вопрос 3
Ваш текущий код уже довольно эффективный, но чтобы его улучшить, можно воспользоваться бинарным поиском вместо полного перебора всех уровней.

Вот как может выглядеть улучшенная реализация:

```javascript
const LVLS = [
  {exp: 10, lv: 1},
  {exp: 25, lv: 2},
  {exp: 45, lv: 3},
  {exp: 70, lv: 4},
  {exp: 100, lv: 5},
];
const EXP = 47;
let lvl = 0;

let left = 0;
let right = LVLS.length - 1;

while (left <= right) {
  let mid = Math.floor((left + right) / 2);

  if (EXP >= LVLS[mid].exp) {
    lvl = LVLS[mid].lv;
    left = mid + 1;
  } else {
    right = mid - 1;
  }
}

console.log(lvl);
```

В этой реализации используется бинарный поиск, который ищет наибольший уровень, суммарный опыт которого меньше или равен заданному опыту EXP. Это позволяет значительно сократить число итераций, особенно если массив LVLS достаточно большой.
<pre><code class="javascript">const LVLS = [
    {exp: 10, lv: 1},
    {exp: 25, lv: 2},
    {exp: 45, lv: 3},
    {exp: 70, lv: 4},
    {exp: 100, lv: 5},
]

console.log(LVLS.reduce((acc, l) =&gt; (47 &gt;= l.exp ? l.lv : acc), 0)); // 3</code></pre> <br/> <blockquote>Все работает, но кажется, что достаточно криво.</blockquote> <br/> Теперь ровнее.
<blockquote>работает, но кажется, что достаточно криво</blockquote> <br/> Да, криво - всегда перебирается весь массив. <br/> <br/> Можно идти от конца к началу до тех пор, пока не встретится подходящий элемент: <br/> <br/> <pre><code class="javascript">let lvl = 0;

for (let i = LVLS.length; i--; ) {
  if (LVLS[i].exp &lt;= EXP) {
    lvl = LVLS[i].lv;
    break;
  }
}</code></pre> <br/> <blockquote>переделать это во что-то более красивое</blockquote> <br/> <pre><code class="javascript">const lvl = LVLS.findLast(n =&gt; n.exp &lt;= EXP)?.lv ?? 0;</code></pre>
Похожие вопросы