109

I am trying to solve a math problem where I take a number e.g. 45, or 111 and then split the number into separate digits e.g. 4 5 or 1 1 1. I will then save each number to a var to run a method on. Does anyone know how to split a number into individual digitals?

For example I have a loop that runs on an array :

for (var i = 0; i < range.length; i++) {
  var n = range[i];
}

For each number, I would like to split its digits and add them together?

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
jonnyhitek
  • 1,521
  • 4
  • 17
  • 31

29 Answers29

137

var num = 123456;
var digits = num.toString().split('');
var realDigits = digits.map(Number)
console.log(realDigits);
Terry Wei
  • 1,521
  • 8
  • 16
Brian Glaz
  • 15,468
  • 4
  • 37
  • 55
81
var number = 12354987,
    output = [],
    sNumber = number.toString();

for (var i = 0, len = sNumber.length; i < len; i += 1) {
    output.push(+sNumber.charAt(i));
}

console.log(output);

/* Outputs:
 *
 * [1, 2, 3, 5, 4, 9, 8, 7]
 */ 

UPDATE: Calculating a sum

for (var i = 0, sum = 0; i < output.length; sum += output[i++]);
console.log(sum);

/*
 * Outputs: 39
 */
Lapple
  • 3,385
  • 20
  • 20
62

You can also do it in the "mathematical" way without treating the number as a string:

var num = 278;
var digits = [];
while (num != 0) {
    digits.push(num % 10);
    num = Math.trunc(num / 10);
}
digits.reverse();
console.log(digits);

One upside I can see is that you won't have to run parseInt() on every digit, you're dealing with the actual digits as numeric values.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • I was trying to solve an algo that would require me to split a number without first turning it to a string, and this worked on positive numbers but not on negative numbers. Negative numbers return empty array. – Hoxtygen Dec 22 '22 at 20:19
  • @Hoxtygen you're correct, for some reason I assumed positive numbers only. I fixed the code, see edit. Essentially, just changed the loop stop condition to stop when it reach zero, while before it also stopped on negative numbers. – Shadow The GPT Wizard Dec 23 '22 at 07:15
  • Sweet, this actually works correctly with large numbers, unlike the top answer! – Stefnotch Jul 07 '23 at 20:46
  • This hasn't been tested with negative numbers, has it? Returning `[ -2, -7, -8 ]` for `-278` seems like an interesting choice. – Stefnotch Jul 07 '23 at 20:57
  • 1
    @Stefnotch tested for not empty, which is the "bug" the was "reported" back in December. But you do raise interesting point, while e.g. "-2" isn't strictly a digit, it does help to know the original number was negative. Easy to just ignore number being negative by `Math.abs()` the input, but if you do want to keep that detail something else is needed. So bottom line, can't know in advance the requirement in such cases. – Shadow The GPT Wizard Jul 08 '23 at 07:16
36

This is the shortest I've found, though it does return the digits as strings:

let num = 12345;

[...num+''] //["1", "2", "3", "4", "5"]

Or use this to get back integers:

[...num+''].map(n=>+n) //[1, 2, 3, 4, 5]
Marco Gaspari
  • 479
  • 5
  • 4
14

I will provide a variation on an answer already given so you can see a different approach that preserves the numeric type all along:

var number = 12354987,
    output = [];

while (number) {
    output.push(number % 10);
    number = Math.floor(number/10);
}

console.log(output.reverse().join(',')); // 1,2,3,5,4,9,8,7

I've used a technique such as the above to good effect when converting a number to Roman numerals, which is one of my favorite ways to begin to learn a programming language I'm not familiar with. For instance here is how I devised a way to convert numbers to Roman numerals with Tcl slightly after the turn of the century: http://code.activestate.com/recipes/68379-conversion-to-roman-numerals/

The comparable lines in my Tcl script being:

  while {$arabic} {
    set digit [expr {$arabic%10}]
    set arabic [expr {$arabic/10}]
Dexygen
  • 12,287
  • 13
  • 80
  • 147
  • 1
    This is sad that first decent use of % operator is so low in answers list – Sergey Orlov Feb 26 '18 at 15:24
  • Thanks for the continued up-votes, but in light of ES5 and/or ES6, this answer is hardly valid anymore. Even as it stands I should have specified `output.unshift` (instead of `push`) thereby making the `reverse()` unnecessary -- a lot people fail to thing of `unshift` – Dexygen May 17 '18 at 10:43
  • @GeorgeJempty, thanks for emphasizing ***preservation of the numeric type***. I spent too much time yesterday unraveling a base conversion problem caused by string input. I would appreciate any updates to this answer you might have related to ES5/ES6 and/or `output.unshift`. – CODE-REaD Sep 26 '18 at 13:38
9

// Split positive integer n < 1e21 into digits:
function digits(n) {
  return Array.from(String(n), Number);
}

// Example:
console.log(digits(1234)); // [1, 2, 3, 4]
le_m
  • 19,302
  • 9
  • 64
  • 74
7

Use String, split and map :

String(number).split("").map(Number);

function splitNum(num) {
    return String(num).split("").map(Number);
}

console.log(splitNum(1523)); // [1, 5, 2, 3]
console.log(splitNum(2341)); // [2, 3, 4, 1]
console.log(splitNum(325)); // [3, 2, 5]
Blackjack
  • 1,322
  • 1
  • 16
  • 21
  • String removes the zeros though. Is there a way to make it so the zeros don't get removed? – Graphics Factory Nov 06 '22 at 06:36
  • Do you mean the zeros after the number? Because those don't get rid of them. If you mean the 0 before the number, how does a variable have a zero before the number? For example 001234 is already a string not an integer – Blackjack Nov 06 '22 at 18:10
5

You can work on strings instead of numbers to achieve this. You can do it like this

(111 + '').split('')

This will return an array of strings ['1','1','1'] on which you can iterate upon and call parseInt method.

parseInt('1') === 1

If you want the sum of individual digits, you can use the reduce function (implemented from Javascript 1.8) like this

(111 + '').split('').reduce(function(previousValue, currentValue){  
  return parseInt(previousValue,10) + parseInt(currentValue,10);  
})
Narendra Yadala
  • 9,554
  • 1
  • 28
  • 43
4

Without converting to string:

function toDigits(number) {
    var left;
    var results = [];

    while (true) {
        left = number % 10;
        results.unshift(left);
        number = (number - left) / 10;
        if (number === 0) {
            break;
        }
    }

    return results;
}
karaxuna
  • 26,752
  • 13
  • 82
  • 117
4

Using String, ... and map

const num = 7890;

const digits = [...String(num)].map(Number);

console.log(digits)

Alternatively, using ... and reduce to get digits and their sum.

const sumOfDigits = num => [...""+num].reduce((acc, dig) => acc + +dig, 0);

console.log('Sum of digits: ', sumOfDigits(7890));
Siva K V
  • 10,561
  • 2
  • 16
  • 29
2

Separate each 2 parametr.

function separator(str,sep) {
    var output = '';
    for (var i = str.length; i > 0; i-=2) {
        var ii = i-1;
        if(output) {
            output = str.charAt(ii-1)+str.charAt(ii)+sep+output;
        } else {
            output = str.charAt(ii-1)+str.charAt(ii);
        }            
    }
    return output;
}
console.log(separator('123456',':')); //Will return 12:34:56
fdrv
  • 852
  • 1
  • 11
  • 21
2

With ES6, you could use Array.from with a stringed number as iterables and Number as mapping function.

const getDigits = n => Array.from(n.toString(), Number);

console.log(getDigits(12345));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

A fun introduction to recursion. This answer takes a Number and returns an array of Number digits. It does not convert the number to a string as an intermediate step.

Given n = 1234,

  • n % 10 will return first (right-moist) digit, 4
  • n / 10 will return 123 with some remainder
  • Using Math.floor we can chop the remainder off
  • Repeating these steps, we can form the entire result

Now we just have to build the recursion condition,

  • If the number is already a single digit (n < 10), return an array singleton of the digit
  • otherwise (inductive) the number is 10 or greater; recur and prepend to the first digit

const digits = (n = 0) =>
  n < 10
    ? [ n ]
    : [ ... digits (Math.floor (n / 10)), n % 10 ]

console.log (digits ())        // [ 0 ]
console.log (digits (1))       // [ 1 ]
console.log (digits (12))      // [ 1, 2 ]
console.log (digits (123))     // [ 1, 2, 3 ]
console.log (digits (11234))   // [ 1, 2, 3, 4 ]

console.log (digits (123456789012))
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2 ]
Mulan
  • 129,518
  • 31
  • 228
  • 259
  • This is really neat, but it does not seem to work in every case. `digits(123456789012)` returns `[-539222987, 2]` – Wondercricket Feb 15 '19 at 16:05
  • @Wondercricket thanks for catching that, I made an update to fix it. That's a behavior of `>>` I don't quite understand. I wonder if it's a bug? – Mulan Feb 16 '19 at 01:16
  • *off-topic:* looking forward to see an answer from you on https://stackoverflow.com/q/54721972/5260024 :) – Jonas Wilms Feb 16 '19 at 13:03
  • cool question, eh? thanks for sharing. looks like B caught the issue already :D – Mulan Feb 16 '19 at 14:40
  • 1
    I really like this solution - it shows mathematical understanding, and who doesn't like a decent use of recursion? :) – glowkeeper Mar 08 '22 at 16:25
2

This also works:

var number = 12354987;
console.log(String(number).split('').map(Number));
iampopov
  • 21
  • 1
1

Shadow Wizard , extended version by Orien

var num:Number = 1523;
var digits:Array = [];
var cnt:int = 0;
while (num > 0) {
    var mod:int = num % 10;
    digits.push(mod * Math.pow(10, cnt))

    num = Math.floor(num / 10);
    cnt++;
}
digits.reverse();
trace(digits);

output:1000,500,20,3

Orien
  • 47
  • 2
  • 7
1

A functional approach in order to get digits from a number would be to get a string from your number, split it into an array (of characters) and map each element back into a number.

For example:

var number = 123456;

var array = number.toString()
.split('')
.map(function(item, index) {
   return parseInt(item);
});

console.log(array); // returns [1, 2, 3, 4, 5, 6]

If you also need to sum all digits, you can append the reduce() method to the previous code:

var num = 123456;

var array = num.toString()
.split('')
.map(function(item, index) {
   return parseInt(item);
})
.reduce(function(previousValue, currentValue, index, array) {
  return previousValue + currentValue;
}, 0);

console.log(array); // returns 21

As an alternative, with ECMAScript 2015 (6th Edition), you can use arrow functions:

var number = 123456;
var array = number.toString().split('').map((item, index) => parseInt(item));
console.log(array); // returns [1, 2, 3, 4, 5, 6]

If you need to sum all digits, you can append the reduce() method to the previous code:

var num = 123456;

var result = num.toString()
.split('')
.map((item, index) => parseInt(item))
.reduce((previousValue, currentValue) => previousValue + currentValue, 0);

console.log(result); // returns 21
Imanou Petit
  • 89,880
  • 29
  • 256
  • 218
1

I used this simple way of doing it.

To split digits

var N = 69;
var arr = N.toString().split('').map(Number)
// outputs [6,9]
console.log( arr ); 

To add them together

console.log(arr.reduce( (a,b) => a+b )); // 15
makkBit
  • 373
  • 2
  • 14
1

And the easiest.... num_string.split('').map(Number)

Try below:

console.log((''+123).split('').map(Number))
Attersson
  • 4,755
  • 1
  • 15
  • 29
1

To just split an integer into its individual digits in the same order, Regular Expression is what I used and prefer since it prevents the chance of loosing the identity of the numbers even after they have been converted into string.

The following line of code convert the integer into a string, uses regex to match any individual digit inside the string and return an array of those, after which that array is mapped to be converted back to numbers.

const digitize = n => String(n).match(/\d/g).map(Number);

SNOSeeds
  • 116
  • 4
1

I might be wrong, but a solution picking up bits and pieces. Perhaps, as I still learning, is that the functions does many things in the same one. Do not hesitate to correct me, please.

const totalSum = (num) => [...num + ' '].map(Number).reduce((a, b) => a + b);

So we take the parameter and convert it to and arr, adding empty spaces. We do such operation in every single element and push it into a new array with the map method. Once splited, we use reduce to sum all the elements and get the total.

As I said, don't hesitate to correct me or improve the function if you see something that I don't.

Almost forgot, just in case:

const totalSum = (num) => ( num === 0 || num < 0) ? 'I need a positive number' : [...num + ' '].map(Number).reduce((a, b) => a + b);

If negatives numbers or just plain zero go down as parameters. Happy coding to us all.

1

I am posting this answer to introduce the use of unshift which is a modern solution. With push, you add to the end of an array while unshift adds to the beginning. This makes the mathematical approach more powerful as you won't need to reverse anymore.

let num = 278;
let digits = [];
while (num > 0) {
    digits.unshift(num % 10);
    num = parseInt(num / 10);
}
console.log(digits);
John David
  • 752
  • 2
  • 9
  • 21
1

And as a one liner.

console.log(BigInt(1e200).toString().split('').reduce((pv, v) => Number(v) + pv, 0));
Jostein S
  • 456
  • 7
0

You can try this.

  var num = 99;

  num=num.toString().split("").map(value=>parseInt(value,10)); //output [9,9]

Hope this helped!

Aditya Raj
  • 327
  • 3
  • 14
  • Breaks on large numbers, try out `1e200.toString().split("")`. That results in `[ "1", "e", "+", "2", "0", "0" ]` – Stefnotch Jul 07 '23 at 20:43
0
function iterateNumber(N, f) {
    let n = N;
    var length = Math.log(n) * Math.LOG10E + 1 | 0;
    for (let i = 0; i < length; i++) {
        const pow = Math.pow(10, length - i - 1)
        let c = (n - (n % pow)) / pow
        f(c, i)
        n %= pow
    }
}
dferenc
  • 7,918
  • 12
  • 41
  • 49
user2584621
  • 2,305
  • 2
  • 15
  • 9
  • 7
    You should explain your answer. Currently, this is just a block of code that doesn't include any comments or help for people trying to learn the concept. – Goose Jan 09 '18 at 22:06
0

('' + 123456789).split('').map( x => +x ).reduce( (a,b) => a+b ) === 45

true

or without map

('' + 123456789).split('').reduce( (a,b) => (+a)+(+b) ) === 45

true

gkelly
  • 268
  • 1
  • 9
0

You can do it in single line, seperate each digits than add them together :

var may = 12987;
var sep = (""+may).split("").map(n=>+n).reduce((a,b)=>a+b);
Stst
  • 11
  • 2
  • This too breaks with large numbers, try running `(""+2e200).split("")`. That will result in `[ "2", "e", "+", "2", "0", "0" ]` – Stefnotch Jul 07 '23 at 20:45
0

This is my short solution.. with sum of number

    function sum (num) {
    let sNumber = num
        .toString()
        .split('')
        .reduce((el1, el2) => {
            return Number(el1) + Number(el2)
        }, 0)
        return sNumber
     }

console.log(sum(123))
console.log(sum(456))

Angel F Syrus
  • 1,984
  • 8
  • 23
  • 43
Todor Markov
  • 507
  • 5
  • 12
  • Breaks on large numbers, try out `1e200.toString().split("")`. That results in `[ "1", "e", "+", "2", "0", "0" ]` – Stefnotch Jul 07 '23 at 20:41
0

javascript has a function for it and you can use it easily.

console.log(new Intl.NumberFormat().format(number));

for example :

console.log(new Intl.NumberFormat().format(2334325443534));
==> 2,334,325,443,534
0
var num = 111,
 separateDigits = num.toString().split(""), i, l = separateDigits.length;

for( i = 0; i < l; ++i ) {
someObject.someMethod( +separateDigits[i] );
}
Esailija
  • 138,174
  • 23
  • 272
  • 326
  • Breaks on large numbers, try out `1e200.toString().split("")`. That results in `[ "1", "e", "+", "2", "0", "0" ]` – Stefnotch Jul 07 '23 at 20:41