考虑将毫秒分解为可读时间单位的问题.想象一下,你有一个能够做到这一点的功能
> breakupMillis(100000000)
Array [ 0, 40, 46, 3, 1 ]
意思是1亿毫秒是1天,3小时,46分钟和40秒.
可以通过接受模数数组来推广该函数,如下所示
> breakup(100000000, [1000, 60, 60, 24])
Array [ 0, 40, 46, 3, 1 ]
该函数可以(假设地)用于其他事情:
> breakup(1000, [8, 8, 8])
Array [ 0, 5, 7, 1 ]
意味着十进制中的1000是八进制中的01750.
这是我写的功能:
const breakup = (n, l) => l.map(p =>
{ const q = n % p; n = (n - q) / p; return q; }).concat(n);
这个功能很好,它甚至是引用透明的,但我有两个完全美观的抱怨.
>地图.这感觉就像减少工作,虽然我不知道如何.
>重写变量n.我根本不喜欢使用var;使用秘密var会使情况变得更糟.
我的问题只是关于第二个问题.如何重新编写函数,使其不使用变量(实际上有所不同)?如果地图消失了,我会把它当成肉汁.
最佳答案 这是另一种方法,你可以使用递归过程和一个小帮助器quotrem – 给出分子n和分母d,返回[< quotient>,< remainder>]
const quotrem = (n, d) => [n / d >> 0, n % d]
const breakup = (n, [x,...xs]) => {
if (x === undefined) {
return [n]
}
else {
let [q, r] = quotrem(n, x)
return [r, ...breakup(q, xs)]
}
}
console.log(breakup(1000, [8, 8, 8]))
// [ 0, 5, 7, 1 ]
console.log(breakup(100000000, [1000, 60, 60, 24]))
// [ 0, 40, 46, 3, 1 ]
如果您对结构化数组不是特别熟悉,可以添加一些帮助程序(isEmpty,head和tail)以更明确的方式与数组交互
const isEmpty = xs => xs.length === 0
const head = xs => xs[0]
const tail = xs => xs.slice(1)
const quotrem = (n, d) => [n / d >> 0, n % d]
const breakup = (n, xs) => {
if (isEmpty(xs)) {
return [n]
}
else {
let [q, r] = quotrem(n, head(xs))
return [r, ...breakup(q, tail(xs))]
}
}
console.log(breakup(1000, [8, 8, 8]))
// [ 0, 5, 7, 1 ]
console.log(breakup(100000000, [1000, 60, 60, 24]))
// [ 0, 40, 46, 3, 1 ]