我当时正在做一个Javascript练习,它需要将一个数字转换成一个由单个数字组成的数组,而我唯一能做到这一点的方法似乎就是将这个数字转换成一个字符串,然后再转换回一个数字。
let numbers = 12345;
Array.from(numbers.toString(10), Number) // [1, 2, 3, 4, 5]
基本上,我想知道这是不是在数字上实现像这样的拆分的最好方法,或者是否有更有效的方法不需要这样的转换。
发布于 2019-07-23 08:14:06
你总是可以用n % 10
得到最小的数字。您可以使用减法和除以10 (或除以底数)删除此数字。这就产生了一个非常简单的循环:
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))
这将以相反的顺序获取数字,因此您必须将结果unshift
到数组中,或者在结束时进行推送和反转。
这样做的好处之一是,您可以通过将10
替换为您选择的基数来查找不同基数的数字:
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))
不过,一旦基数大于10,就必须将这些数字映射到适当的字母。
发布于 2019-07-23 08:03:50
一种方法是迭代数字的数量,逐个计算每个模数的差值,然后根据每次迭代的结果填充输出列表。
识别基数为10的输入中的位数的快速方法如下:
Math.floor(Math.log(input) / Math.LN10 + 1) // 5 for input of 12349
接下来,遍历这个范围,对于每个迭代,计算当前和先前迭代的基数,并根据这些计算输入的模数。然后,从模数计算的差值中得出当前迭代的数字,如下所示:
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]');
https://stackoverflow.com/questions/57155049
复制相似问题