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変数(breakとにかく効果的に使用されていなかった)を削除しbreak、条件をに変更しますstart <= @
  • を1つだけ使用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 に答える