2

下面的代码有效,但我想知道是否有更好的方法可以使用我不熟悉的咖啡脚本的一些功能。

问题是,我需要对项目进行分页,但分页每次都会增加。

如果我以数字 20 为例,它将创建以下页面:

1 - 3 4 - 7 8 - 15 16 - 20

我有以下测试和代码确实通过了:

module 'Remainder',
  setup: ->
    @remainder = 20

test 'splits remainder incrementally', ->
  parts = @remainder.increasingSplit()
  equal parts[0], '1 - 3', ''
  equal parts[1], '4 - 7', ''
  equal parts[2], '8 - 15', ''
  equal parts[3], '16 - 20', ''

Number.prototype.increasingSplit = ->
  start = 1
  nextSplit = 3
  parts = []
  finished = false
  while !finished
    if nextSplit > @
      parts.push "#{start} - #{@}"
      break

    parts.push "#{start} - #{nextSplit}"
    start = nextSplit + 1
    nextSplit = nextSplit * 2 + 1

  parts
4

1 回答 1

1

在不过多更改算法的情况下,您可以尝试以下操作:

Number::increasingSplit = ->
  start = 1
  nextSplit = 3
  parts = []
  while start <= @
    parts.push "#{start} - #{Math.min nextSplit, @}"
    start = nextSplit + 1
    nextSplit = nextSplit * 2 + 1
  parts

变化是:

  • 替换.prototype::,
  • 删除变量(因为无论如何finished都没有被有效使用)并完全删除并将条件更改为,breakbreakstart <= @
  • 仅使用一个,以 和 之间的parts.push <part>最小值作为顶部。nextSplit@

另外,我建议不要在这种情况下扩展 Number 原型。扩展原始类型的原型有时会导致奇怪的问题,例如:

Number::isFour = -> @ is 4
console.log 4.isFour() # -> false

发生这种情况是因为该函数内部@将是一个 Number对象而不是原始数字,因此使=== 4比较总是失败。isFour如果您将其定义为独立函数,则不会发生这种情况:

isFour = (n) -> n is 4
console.log isFour 4 # -> true

所以,我更喜欢这个版本incrasingSplit

increasingSplit = (n) ->
  start = 1
  nextSplit = 3
  parts = []
  while start <= n
    parts.push "#{start} - #{Math.min nextSplit, n}"
    start = nextSplit + 1
    nextSplit = nextSplit * 2 + 1
  parts

最后,如果您不介意递归,您可以使用更 FP 风格的算法 :)

increasingSplit = (n, start = 1, nextSplit = 3) ->
  if start > n
    []
  else
    part = "#{start} - #{Math.min nextSplit, n}"
    rest = increasingSplit n, nextSplit + 1, nextSplit * 2 + 1
    [part, rest...]
于 2012-10-27T23:42:11.247 回答