#javascript
#javascript
Вопрос:
Мне был дан этот тест для его решения, и я его решаю, тест запрашивал возврат суммы цифр, и это довольно легко вернуть, но загвоздка заключалась в том, чтобы вернуть его (если число отрицательное, первая цифра должна считаться отрицательной)
, например.
let output = sumDigits(1148);
console.log(output); // --> 14
let output = sumDigits(-316);
console.log(output); // --> 4
как я уже сказал, я решаю это так
const sumDigits = num => {
let ar = num.toString().split('') //Stringify the num and convert it to an array
let minSum = 0 // initialize the minSum counter and set to the value of 0
let plsSum = 0 // initialize the plsSum counter and set to the value of 0
//checking if the array start with '-', and if it's i'm going to remove it.
if (ar[0] === '-') {
ar.splice(0, 1)
ar.reduce((a, b) => minSum = Math.abs(a - b)) // subtracting the arrray of numbers and convet it to number after removing the first char.
}
// iterate over the array.
for (let i = 0; i < ar.length; i ) {
// adding the sum of array numbers to the initial var and convert it to a number
plsSum = Number(ar[i])
}
//returning the minSum and plsSum
if (minSum) {
return minSum
} else {
return plsSum
}
}
let output = sumDigits(1148)
console.log(output) // --> 14
let output2 = sumDigits(-316)
console.log(output2) // --> 4
но пока я искал, я нашел этот код в одной строке с reduce, и часть этого кода я не смог понять, вот почему я спрашиваю вас, ребята.
вот код
const sumDigits = num =>String(num).split('').reduce((a,v,idx,arr)=> v === '-' ? (v = 0, arr[idx 1] *= -1, a v) :a v,0)
итак, давайте разберем это.
String(num).split('')
в этой части они вводят его в строку и преобразуют в массив. ✔
reduce((a,v,idx,arr)
в этой части они инициализировали reduce с помощью 4 аргументов. ✔
v === '-' ?
в этой части они проверяют, v
равно ли '-'
v
, но вопрос в том, будет ли это начинаться с 1 в первом выводе (1148), и это будет начинаться с 3 во втором выводе (-316) a
, потому что это будет начинаться с 1 и с ‘-‘, не так ли? затем они устанавливают (v = 0). и затем они умножаются arr[idx 1] *= -1
на -1 мой вопрос в том, почему?
И если кто-то не возражает против объяснения остальной части кода, это было бы очень ценно.
Заранее благодарю.
Ответ №1:
Вы можете использовать Math.abs
и преобразовать число в строку перед разделением, а затем использовать reduce для вычисления суммы. Перед возвратом из функции проверьте, меньше или больше 0 входные данные и, соответственно, предпримите шаги
function sumDigits(num) {
// toString will convert to string so an array of string can be created
const sum = Math.abs(num).toString().split('').reduce((acc, curr) => {
// converting string to number before adding with previous digit
// else it will do string concatenation instead of mathematical addition
acc = curr;
return acc
}, 0);
return num < 0 ? -1 * sum : sum;
}
let output = sumDigits(1148);
console.log(output); // --> 14
let outpu2t = sumDigits(-316);
console.log(outpu2t); // --> -10
Комментарии:
1. ваш код должен возвращать
sumDigits(-316)
//—>4
но он возвращает-10
Ответ №2:
Краткий ответ: arr[idx 1] *= -1
для прямого преобразования следующего элемента в массиве в отрицательное целое число.
Вы можете попробовать следующий код на игровой площадке Javascript, чтобы увидеть значения переменных для каждого шага цикла для лучшего понимания: (это расширенная версия кода, которую вы пытаетесь понять)
function sum(num) {
s = String(num)
.split('')
.reduce(function (a, v, idx, arr) {
console.log('a=', a, 'v=', v, 'idx=', idx, 'arr=', arr);
if (v === '-') {
v = 0;
arr[idx 1] *= -1;
a = v;
} else {
a = v;
}
return a;
}, 0);
return s;
}
console.log(sum(1148));
console.log(sum(-316));
Комментарии:
1. Спасибо @kevin.bui, за ваше объяснение 🙏
Ответ №3:
Я собираюсь сосредоточиться на части метода reduce. Метод reduce Array может выдавать два аргумента, первый указывает на обратный вызов, который «уменьшит» массив, этот обратный вызов может выдавать 4 аргумента:
- Накопитель
- Текущее значение
- Текущий индекс
- Массив
второй аргумент метода reduce указывает, с какого значения будет запускаться аргумент Acumulator обратного вызова.
Однажды объяснил, что в примере, который вы видели, он указывает, что накопитель будет начинаться со значения 0:
.reduce(<...>, 0)
Затем, на первой итерации метода reduce, первым значением текущего значения будет 0-индексированное значение массива.
Если мы рассмотрим случай, когда num
является -316
, то:
-
Первая итерация: переменные обратного вызова будут:
a = 0 v = '-' idx = 0 arr = ['-', '3', '1', '6']
Процесс будет:
v === '-' //true, then: v = 0 arr[idx 1] *= -1 //here, he are converting the value next to the sign to a negative value a v //then, he add the v value to the acumulator with the corresponding sign.
-
Вторая итерация:
Переменные обратного вызоваa = 0 v = -3 idx = 1 arr = ['-', -3, '1', '6']
Процесс:
v === '-' //false, then: a v //a = 0, v = -3. 0 (-3) = -3 (Number)
И я думаю, что вы можете расшифровать остальную часть истории.
Комментарии:
1. Спасибо @Alejandro Gomez, твое объяснение очень подробное, спасибо, чувак 🙏