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

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

```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 достаточно большой.
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) => (47 >= l.exp ? l.lv : acc), 0)); // 3

Все работает, но кажется, что достаточно криво.

Теперь ровнее.
работает, но кажется, что достаточно криво

Да, криво - всегда перебирается весь массив.

Можно идти от конца к началу до тех пор, пока не встретится подходящий элемент:

let lvl = 0;

for (let i = LVLS.length; i--; ) {
  if (LVLS[i].exp <= EXP) {
    lvl = LVLS[i].lv;
    break;
  }
}

переделать это во что-то более красивое

const lvl = LVLS.findLast(n => n.exp <= EXP)?.lv ?? 0;
Похожие вопросы