2012-11-16 44 views
2

下面的代码通过了Ruby 1.8/1.9的测试,但是当我在Ruby 1.9.2上运行these tests时,我没有得到Array#sum的方法错误。例如,总结一个数组

NoMethodError: undefined method `sum' for [3.2, 3.0, 1.5, 0.73, 0.47, 0.23]:Array 

我碰到inject(:+),但是当我试图取代它在sum是,它创造了其他问题。有两种使用sum的方法,time_requiredbalance_queues。在第二种方法中,将其加入旧代码q1.sum - q2.sum中很复杂。尽可能多的细节/解释会有帮助。

class FairDistribution 
    def initialize(jobs, num_of_queues) 
    @queues = [ jobs.sort.reverse ] 
    (num_of_queues - 1).times { @queues << [] } 

    # Balance the queues until they are perfectly balanced 
    while !balance_all_queues do; end 
    end 

    # Time required for all queues processing 
    def time_required 
    @queues.map { |q| q.sum }.max      #SUM 
    end 

    # The actual distribution of jobs across the queues 
    def distribution 
    @queues 
    end 

    private 

    # Runs through all queues and balances them against each other. 
    # Makes one pass only and returns FALSE if there was nothing changed 
    # during the pass. 
    def balance_all_queues 
    updated = false 

    @queues.each_with_index do |q1, qi1| 
     (qi1+1 ... @queues.size).each do |qi2| 
     res = balance_queues(q1, @queues[qi2]) 
     updated ||= res 
     end 
    end 

    return !updated 
    end 

    # Balances the two queues between themselves by finding the best possible 
    # swap of jobs between them. If there's nothing to be improved, returns FALSE. 
    def balance_queues(q1, q2) 
    delta = q1.sum - q2.sum       #SUM 
    return false if delta == 0 

    best_swap  = nil 
    best_swap_delta = delta.abs 

    q1.each_combination do |c1| 
     best_swap, best_swap_delta = choose_better_swap(c1, [], delta, best_swap, best_swap_delta) 

     q2.each_combination do |c2| 
     best_swap, best_swap_delta = choose_better_swap(c1, c2, delta, best_swap, best_swap_delta) 
     end 
    end 

    best_swap.apply(q1, q2) unless best_swap.nil? 

    return !best_swap.nil? 
    end 

    # Sees if the swap we have at hand is better than our current best 
    # swap and replaces the latest if it is. 
    def choose_better_swap(c1, c2, delta, best_swap, best_swap_delta) 
    unless c1 == c2 
     s = Swap.new(c1, c2, delta) 
     best_swap, best_swap_delta = s, s.delta if s.delta < best_swap_delta 
    end 

    return best_swap, best_swap_delta 
    end 
end 

回答

8

Enumerable#sum由ActiveSupport(Ruby on Rails的一部分)提供。如果您已经安装了active_support宝石,你可以通过添加给你的脚本的顶部使用[].sum

require 'active_support/core_ext/enumerable' 

尝试使用.inject(0, :+)。这将导致空数组为'0',并可能导致您的问题与inject

+0

谢谢,解决了'总和'问题。只是为了揭示另一个。如有必要,将发布另一个问题。欢呼声 – BrainLikeADullPencil

+0

太棒了!另请参阅我的编辑,了解为什么'sum'在纯Ruby中不可用。 – ndbroadbent

+0

看到它,欣赏尽可能多的信息。谢谢。 – BrainLikeADullPencil