考虑将毫秒分解为可读时间单位的问题。想象一下,你有一个能够做到这一点的功能
> 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);
这个功能很好,甚至是引用透明的,但我有两个完全美观的抱怨。
map
。这感觉就像reduce
的工作,虽然我不知道如何。n
。我根本不喜欢使用var
;使用秘密 var
会让情况变得更糟。我的问题只是关于第二个问题。如何重新编写函数,使其不使用变量(实际上有所不同)?如果map
消失,我会将其视为肉汁。
答案 0 :(得分:2)
这是另一种方法,你可以使用递归过程和一个小助手quotrem
- 给出分子n
和分母d
,返回[<quotient>, <remainder>]
< / p>
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 ]
答案 1 :(得分:0)
这感觉就像是
reduce
的工作,虽然我不知道如何。
迭代数组的所有内容都可以使用reduce
完成: - )
我们需要通过两件事(对于累加器):我们仍有休息的数字和结果列表。我们可以使用ES6解构和数组作为元组:
function breakup(n, units) {
const [n, res] = units.reduce(([n, res], u) => {
const q = n % u;
res.push((n-q) / u);
return [q, res];
}, [n, units]);
return [n, ...res];
}
但push
仍然很难看。不仅因为它变异(我们也可以使用concat
),但我们真正想要的是一个抽象它的函数。不幸的是,JS中不存在这些 - 我们正在寻找scan或mapping accumulation。我们可以写
function breakup(n, units) {
const [rest, res] = units.mapAccum((n, u) => {
const q = n % u;
return [q, (n-q) / u];
}, [n, units]);
return [...res, rest];
}
function breakup(n, units) {
const mods = units.scan((n, u) => Math.floor(n/u), units);
return mods.map((q, i) => i<units.length ? q % units[i] : q);
}
我会将这些(功能,高效,可读等)的实现留给读者作为练习。
答案 2 :(得分:0)
我会建议这段代码:
Observable<MyResponseStream>