下面的代码有效,但我想知道是否有更好的方法可能会使用我不熟悉的coffeescript的一些功能。
问题在于,我需要分页项目,但每次都会增加分页。
如果我以数字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
答案 0 :(得分: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
变量(由于break
无效而未被有效使用)和break
并且将条件更改为start <= @
,parts.push <part>
,最小值在nextSplit
和@
之间。另外,我建议不要在这种情况下扩展数字原型。扩展原始类型的原型有时会导致奇怪的问题,例如:
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...]