用于循环重构的coffeescript

时间:2011-11-21 10:15:20

标签: coffeescript

我对coffeescript很陌生,我想知道是否有更多有经验的用户可以指出重构以下代码:

splitCollection: =>
  maxLength = Math.ceil(@collection.length / 3)

  sets = Math.ceil(@collection.length / maxLength)
  start = 0    

  for x in [1..sets]   
    if x != sets
      @render new BusinessUnits(@collection.models.slice(start, (maxLength + start)))
    else
      @render new BusinessUnits(@collection.models.slice(start, (@collection.length)))
    start+= maxLength

coffeescript中似乎没有一个while循环似乎表明了一个更好的机制。

任何建议表示赞赏。

3 个答案:

答案 0 :(得分:5)

看起来您正在使用Backbone.js,其中包含具有groupBy功能的Underscore.js。

您可以创建“bucketNumber”功能:

bucketNumber = (value, index) ->
    Math.floor( index / @collection.length * 3 )

然后将您的收藏分组:

sets = @collection.groupBy bucketNumber

现在,假设有10个项目,sets应该是这样的:

{0: [{}, {}, {}], 1: [{}, {}, {}], 2: [{}, {}, {}, {}]}

从这里开始,它变得相当直接

for bucketNumber, bucket of sets
    @render new BusinessUnits( bucket )

这是jsFiddle显示其实际效果

答案 1 :(得分:1)

您无需两次跟踪您的位置,x就足够了:

splitCollection: =>
    setSize = Math.ceil @collection.length / 3
    sets = Math.ceil @collection.length / maxLength

    for x in [1..sets]
        @render new BusinessUnits @collection.models[x * setSize...(x+1) * setSize]

请注意,传递slice一个大于数组长度的结尾没有错。

答案 2 :(得分:0)

如果我理解你的代码,你想要分成3个部分的数组(最后一个可以有更少的项目)。在这种情况下,为任务编写可重用的抽象。使用underscore

splitCollection: =>
  group_size = Math.ceil(@collection.size() / 3)
  _.each _(@collection.models).inGroupsOf(group_size), (group) ->
    @render(new BusinessUnits(group))

_.inGroupsOf可以写成:

_.mixin({
  inGroupsOf: function(array, n) {
    var output = [];
    for(var index=0; index < array.length; index += n) {
      output.push(array.slice(index, index+n));
    }
    return output;
  }
});