Я играл с функциональным программированием и некоторыми задачами, которые ставятся на таких сайтах, как Codewars (в JavaScript). Одна из задач, которую я предпринял, состояла в том, чтобы найти цифровой корень входного целого числа n (то есть сумму каждой из отдельных цифр n). Мне бы очень хотелось помочь с ее исправлением, но с использованием функциональной парадигмы, потому что я уже выполнил эту задачу другими способами с помощью методов ООП. Используемый код выглядит следующим образом:

const digitalRoot = n => {
  let arr = n.toString().split('').map(x => parseInt(x, 10)), sum = 0;
  for (let i = 0; i < arr.length; i++) {
    sum += arr[i];
  }
  return sum;
};

Я не уверен, почему это не работает в большинстве случаев. Например, он возвращает следующее:

digitalRoot(15); //returns 15 instead of 6
digitalRoot(108); //returns 108 instead of 9
digitalRoot(20); //returns 20 instead of 2

Однако в некоторых случаях это работает:

digitalRoot(16); //returns 7 as expected
digitalRoot(0); //returns 0 as expected

Может ли кто-нибудь объяснить мне, в чем проблема с этим и как я мог бы исправить это? Я не уверен, что он продолжает обрабатываться как строка, несмотря на то, что parseInt используется или как. Пожалуйста, дайте мне знать, если преобразование в строку, а затем в массив и т. Д. Является плохой практикой и / или неправильным подходом. Большое спасибо заранее!

2
Nick M 20 Авг 2018 в 22:13

3 ответа

Лучший ответ

Вы должны добавить числа вместе с уменьшением вместо использования карты, особенно если вы собираетесь использовать «функциональный» JavaScript:

const rootNum = n =>
  n.toString().split('').reduce((all, current)=>parseInt(current) + all, 0);

console.log(rootNum(1));
console.log(rootNum(20));
console.log(rootNum(440));
console.log(rootNum(1012340));
console.log(rootNum(1021394812));
2
Derek Pollard 20 Авг 2018 в 19:25

В случае, если кому-то было интересно, я натолкнулся на математическую формулу для этого в Раздел Java переполнения стека, который устранял бы необходимость в циклах, рекурсиях или других вызовах других функций.

Получающийся код:

const digitalRoot = n => 1 + (n - 1) % 9;

Это зависит от математических свойств чисел, которые обсуждаются здесь .

0
Nick M 20 Авг 2018 в 21:51

Функциональное решение может быть рекурсивным методом. Пока n не равен 0, получите последнюю цифру, используя оператор остатка (%) и удалите его из числа, разделив на 10 и округлив результаты.

const digitalRoot = n => 
  n && n % 10 + digitalRoot(Math.floor(n / 10));
  
console.log(digitalRoot(15));
console.log(digitalRoot(108));
console.log(digitalRoot(20));
console.log(digitalRoot(16));
console.log(digitalRoot(0));
0
Ori Drori 20 Авг 2018 в 19:40
51937137