问题描述
考虑将毫秒分解为可读时间单位的问题.假设您有一个函数可以做到这一点
Consider the problem of decomposing milliseconds into readable time units. Imagine you had a function that did that
> breakupMillis(100000000)
Array [ 0, 40, 46, 3, 1 ]
表示1亿毫秒恰好是1天3小时46分钟40秒.
meaning that 100 million milliseconds is 1 day, 3 hours, 46 minutes, and 40 seconds, exactly.
可以通过接受这样的模数数组来泛化该函数
The function could be generalized by accepting an array of moduli, like this
> breakup(100000000, [1000, 60, 60, 24])
Array [ 0, 40, 46, 3, 1 ]
该功能(假设)可以用于其他用途:
That function could be used (hypothetically) for other things:
> breakup(1000, [8, 8, 8])
Array [ 0, 5, 7, 1 ]
表示十进制的1000是八进制的01750.
meaning that 1000 in decimal is 01750 in octal.
这是我为此编写的函数:
Here is the function I wrote to do this:
const breakup = (n, l) => l.map(p =>
{ const q = n % p; n = (n - q) / p; return q; }).concat(n);
此功能很好,它甚至是参照透明的,但是我有两个完全是审美的抱怨.
This function is fine, it's even referentially transparent, but I have two, entirely esthetic, complaints.
-
map
.感觉像是reduce
的工作,尽管我不知道怎么做. - 重写变量
n
.我根本不喜欢使用var
;使用秘密var
会使情况变得更糟.
- the
map
. This feels like a job forreduce
, though I don't see how. - rewriting the variable
n
. I don't like to usevar
at all; using a secretvar
makes it worse.
我的问题只是第二个问题.如何重新编写该函数,使其不使用任何变量(实际上有所不同)?如果map
消失,我将其视为肉汁.
My question is only about the second. How do I re-write the function so it uses no variable (that actually vary)? If the map
disappears, I'll take that as gravy.
推荐答案
这是使用递归过程和小帮手quotrem
的另一种方法-给定一个分子n
和一个分母d
,返回[<quotient>, <remainder>]
Here's another way you can do it using a recursive procedure and a little helper quotrem
– which given a numerator n
, and a denominator d
, returns [<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
)以更明确的方式与数组进行交互
If you're not particularly comfortable with the destructured array, you can add a few more helpers (isEmpty
, head
, and tail
) to interact with the array in a more explicit way
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 ]
这篇关于从功能上将整数分解为大块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!