Reputation: 21
I was working on a Javascript exercise that required a number to be converted into an array of single digits and the only way I can seem to achieve this is by converting the number into a string and then converting it back to a number.
let numbers = 12345;
Array.from(numbers.toString(10), Number) // [1, 2, 3, 4, 5]
Basically, I'm wondering if this is the best way to achieve a split like this on a number or if there is a more efficient method that doesn't require such a conversion.
Upvotes: 2
Views: 668
Reputation: 30360
One approach would be to iterate through the number of digits and calculate the difference of each modulo by base, and then populate the output list from the result of each iteration.
A quick way to identify the number of digits in your base 10 input would be the following:
Math.floor(Math.log(input) / Math.LN10 + 1) // 5 for input of 12349
Next, iterate through this range and for each iteration, calculate the base of the current and previous iterations, and perform module of the input against these. The digit for the current iteration is then derived from the difference of the modulo calculations like this:
function arrayFromInput(input) {
const output = [];
for (let i = 0; i < Math.floor(Math.log(input) / Math.LN10 + 1); i++) {
const lastBase = Math.pow(10, i);
const nextBase = Math.pow(10, i + 1);
const lastMod = input % lastBase;
const nextMod = input % nextBase;
const digit = (nextMod - lastMod) / lastBase;
output.unshift(digit);
}
return output;
}
console.log(arrayFromInput(12345), '= [1,2,3,4,5]');
console.log(arrayFromInput(12), '= [1,2]');
console.log(arrayFromInput(120), '= [1,2 0]');
console.log(arrayFromInput(9), '= [9]');
console.log(arrayFromInput(100), '= [1,0,0]');
Upvotes: 0
Reputation: 92440
You can always get the smallest digit with n % 10
. You can remove this digit with subtraction and division by 10 (or divide and floor). This makes for a pretty simple loop:
function digits(numbers){
if (numbers == 0) return [numbers]
let res = []
while (numbers){
let n = numbers % 10
res.push(n)
numbers = (numbers - n) / 10
}
return res.reverse()
}
console.log(digits(1279020))
This takes the numbers in reverse order so you either have to unshift
the results on to the array or push and reverse at the end.
One of the nice things about this, is that you can find the digits of different bases by swapping out 10
for a the base of your choice:
function digits(numbers, base){
if (numbers == 0) return [numbers]
let res = []
while (numbers){
let n = numbers % base
res.push(n)
numbers = (numbers - n) / base
}
return res.reverse()
}
// binary
console.log(digits(20509, 2).join(''))
console.log((20509).toString(2))
// octal
console.log(digits(20509, 8).join(''))
console.log((20509).toString(8))
Although once your base is larger than 10 you will have to map those digits to the appropriate letters.
Upvotes: 1