Рассчитать результат значений в массиве
Всем привет! В массиве размещены результаты спортивных событий. Победа, ничья и проигрыш дают соответственно 3, 1 и 0 балла. Нужно высчитать из данных в массиве, сколько очков заработала команда.
По логике нужно методом forEach перебрать весь массив и через условные операторы вывести результат. Видимо, где-то допустил ошибку и функция не работает корректно.
Подскажите, пожалуйста, где ошибка и что исправить?
Спасибо.
let arr1 = ['100:90', '110:98', '100:100', '95:46', '54:90', '99:44', '90:90', '111:100'];
function countPoints(score) {
let points;
score.forEach(function(el) {
let i = 0;
let each = parseInt(el[i].split(':'));
if(each[0] > each[1]){
return points += 3;
} else if(each[0] === each[1]){
return points += 1
} else {
return points +=0;
}
});
return points;
}
console.log(countPoints(arr1));
Ответы (2 шт):
let arr1 = ['100:90', '110:98', '100:100', '95:46', '54:90', '99:44', '90:90', '111:100'];
function countPoints(score) {
let points = 0;
score.forEach(function(el) {
let each = el.split(':').map(Number);
if (each[0] > each[1]) {
points += 3;
} else if (each[0] === each[1]) {
points += 1;
}
});
return points;
}
console.log(countPoints(arr1));
Ошибки:
pointsне инициализирована числовым значением, поэтому результатом суммированиия чисел с этой переменной всегда будетNaN- сплит первого символа строки (
el[i]) здесь всегда возвращает массив с одним элементом (с этим символом) попадающим вeach[0]- поэтомуeach[1]всегда возвращаетundefined, и кpointsвсегда прибавляется0 - результаты сплита не приводятся к числовым значениям, поэтому сравнение в каждом случае алфавитное (в соответствии с которым
'10' < '2', и т.д.)
Код можно значительно упростить, используя для вычисления очков одно математическое выражение (вместо двух проверок):
let arr1 = ['100:90', '110:98', '100:100', '95:46', '54:90', '99:44', '90:90', '111:100'];
function countPoints(scores) {
let points = 0;
for (const score of scores) {
const [left, right] = score.split(':');
points += Math.floor((Math.sign(left - right) + 1) * 1.5); // += <3|1|0>
}
return points;
}
console.log(countPoints(arr1));
Math.sign(left - right) возвращает знак разности (при ее вычислении, типкаст строк к числам выполняется автоматически) с единичным значением или нулем: +1|0|-1;
Прибавляем единицу чтобы получить 2|1|0, соответственно;
Умножением на 1.5 с отбрасыванием дробной части результата (Math.floor) получаем 3|1|0, что и требуется.
Для программера знакомого с операциями округления вниз и взятия знака, такое выражение будет читаемее "лапши" условных операторов. Комменты тоже помогают.
В целом, я бы записал еще попроще для себя (но увы, редьюс может пугать, хотя он няшка):
const countPoints = scores => scores.reduce((rslt, score) => {
const [left, right] = score.split(':');
return rslt += ~~((Math.sign(left - right) + 1) * 1.5); // += <3|1|0>
}, 0);
Если же хочется оставить на подсчете именно условия, то имхо предпочтительнее тернарник - его вроде почти все читают легко, даже начинающие:
points += (left > right) ? 3
: (left === right) ? 1
: 0;
Оформление это конечно дело вкуса, в нем нет каких-то определенных правил :)