从功能上将整数分解为大块 [英] Breaking an integer up into chunks, functionally

查看:42
本文介绍了从功能上将整数分解为大块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑将毫秒分解为可读时间单位的问题.假设您有一个函数可以做到这一点

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 for reduce, though I don't see how.
  • rewriting the variable n. I don't like to use var at all; using a secret var 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 ]

如果您对结构化数组不太满意,可以添加更多的帮助器(isEmptyheadtail)以更明确的方式与数组进行交互

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 ]

这篇关于从功能上将整数分解为大块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆