红宝石sort_by!用于对象数组

时间:2018-10-30 19:31:28

标签: arrays ruby sorting

好的,我知道我只是在做些愚蠢的事情,但是我无法使它正常工作。

我有一个机会对象

class Opportunity
  attr_accessor :effort
  attr_accessor :value

  def initialize(effort,value)
    # set values to 1 + the Rayleigh distribution (rounded) 
    @effort = 1 + (effort * Math.sqrt(0-2*Math.log(1-rand()))).round
    @value = 1 + (value * Math.sqrt(0-2*Math.log(1-rand()))).round
  end
end

我将其中的一组推入数组(这是另一个对象的属性),然后我想按特定的属性对它们进行排序(例如努力)

    # Order the working backlog
    #  (see https://ruby-doc.org/core-2.4.3/Array.html#method-i-sort_by-21)
    puts workingBacklog.backlog[0].effort
    workingBacklog.backlog.sort_by! {|opA,opB| opA.effort <=> opB.effort }

这里是示例输出...

6
3cmc.rb:57:in `block (2 levels) in <main>': undefined method `effort' for 
nil:NilClass (NoMethodError)
    from 3cmc.rb:57:in `each'
    from 3cmc.rb:57:in `sort_by'
    from 3cmc.rb:57:in `sort_by!'
    from 3cmc.rb:57:in `block in <main>'
    from 3cmc.rb:51:in `each'
    from 3cmc.rb:51:in `<main>'

所以我知道那里有一个非NULL对象的数组,因为输出的第一行上的“ 6”是非null的。但是在那之后,看起来像是众所周知的轮子脱落了。到底发生了什么事?

2 个答案:

答案 0 :(得分:3)

sort方法需要一个比较块(a与b),但是sort_by方法仅接受一个参数,该元素已排序,并且如果需要,您应该返回转换后的版本,即您希望的排序方式。

在您的情况下就是这样:

backlog.sort_by! { |e| e.effort }

或更简洁地说:

backlog.sort_by!(&:effort)

如果使用正确的方法,您的原始代码将起作用:

backlog.sort! {|opA,opB| opA.effort <=> opB.effort }

sort_by替代代码相比,这里的代码要多得多,但它的工作原理相同。通常,sort_by的性能更好,每次排序仅转换一次。另一个函数必须每个 comparison 进行一次转换,其中通常比数组中的条目多得多,尤其是在较大的数组大小下。

注意::在Ruby中,大写字母具有重要的上下文含义,因此变量和方法名称应仅为lower_case形式。大写字母保留用于ClassNameCONSTANT_NAME情况。

答案 1 :(得分:-1)

首先,fix your sort_by as per @tadman's answer

var
  

所以我知道那里有一个非NULL对象的数组,因为输出的第一行中的“ 6”是非null的。

您仅检查了var coalPileHolding = 0 if let coalPile = Int(coalPileLabel.text!) { let totalCoal = dailyCoalAccumulate + coalPile coalPileHolding = Int(coalPileHoldingLabel.text!) ?? 0 if totalCoal > coalPileHolding { coalPileHolding = totalCoal } coalPileLabel.text = String(totalCoal) UserDefaults.standard.set(totalCoal, forKey:"totalCoal") } callOutLabel.text = String(dailyCoalAccumulate) 的第一个元素。在您的backlog.sort_by!(&:effort) 数组中可能还有workingBacklog.backlog

nil查找backlog

nil

这是一个也重现错误的示例。

select.with_index