Запрашивает объяснение некоторых частей кода

#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 аргумента:

  1. Накопитель
  2. Текущее значение
  3. Текущий индекс
  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, твое объяснение очень подробное, спасибо, чувак 🙏