@Boria321

Почему в корзине считается только последний discount?

Помогите пожалуйста найти баг или исправить ошибку, при подсчете скидки из второго массива берет только последний объект. Возможно есть лучший способ для решения такой задачи.
function totalCost(goods, discounts) {
  let count = 0;
  let sum = 0;
  for (let i in discounts) {
    let str = discounts[i].discount.replace("%", "");
    str = str / 100;
    discounts[i].discount = str;
  }
  for (let i in goods) {
    if (discounts.length === 0) {
      count = goods[i].value * goods[i].amount;
    }
    for (let j in discounts) {
      if (goods[i].name === discounts[j].name) {
        count =
          (goods[i].value - goods[i].value * discounts[j].discount) *
          goods[i].amount;
      } else {
        count = goods[i].value * goods[i].amount;
      }
    }
    sum += count;
    console.log(count, goods[i].name);
  }
  console.log("sum = " + sum);
}
totalCost(
  [
    { name: "Milk", value: 10, amount: 2 },
    { name: "Vegetables", value: 10, amount: 1 },
    { name: "Meat", value: 50, amount: 1 },
    { name: "Salt", value: 10, amount: 3 },
  ],
  [
    { name: "Milk", discount: "50%" },
    { name: "Vegetables", discount: "50%" },
    { name: "Salt", discount: "50%" },
  ]
);
  • Вопрос задан
  • 77 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
for (let i in goods) {
  if (discounts.length === 0) {
    count = goods[i].value * goods[i].amount;
  }
  for (let j in discounts) {
    if (goods[i].name === discounts[j].name) {
      count =
        (goods[i].value - goods[i].value * discounts[j].discount) *
        goods[i].amount;
    } else {
      count = goods[i].value * goods[i].amount;
    }
  }
  sum += count;
  console.log(count, goods[i].name);
}

Зачем на каждой итерации цикла, ищущего скидку, пересчитывать цену? Предположим, нашли скидку для текущего товара, что дальше? Дальше, на следующей итерации, цена будет рассчитана заново, но уже без скидки - ведь объект скидки будет другим, будет соответствовать другому товару. Исключение - если скидка найдена на последней итерации.

Правильно будет вычислять до цикла сумму без скидки, искать в цикле скидку, если нашли - пересчитывать со скидкой, прерывать цикл:

for (const n of goods) {
  let s = n.value * n.amount;
  for (const m of discounts) {
    if (n.name === m.name) {
      s *= 1 - m.discount;
      break;
    }
  }
  sum += s;
}

Возможно есть лучший способ для решения такой задачи.

function totalCost(goods, discounts) {
  discounts = Object.fromEntries(discounts.map(n => [ n.name, 1 - parseFloat(n.discount) / 100 ]));
  return goods.reduce((acc, n) => acc + n.value * n.amount * (discounts[n.name] ?? 1), 0);
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы