Robot Has No Heart

Xavier Shay blogs here

A robot that does not have a heart

Array#collapse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module CoreExtensions
  module Array
    def collapse
      self.inject([]) do |a, v|
        if existing = a.find {|o| o.eql?(v)}
          yield(existing, v)
        else
          a << v
        end
        a
      end
    end
  end
end

Array.send(:include, CoreExtensions::Array)

Kind of handy for reporting, where you need to collapse line items into a summary. This example may make it clear:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Item < Struct.new(:code, :quantity)
  def eql?(b)
    code == b.code
  end

  alias_method :==, :eql?

  def hash
    code.hash
  end

  def to_s
    "#{code} - #{quantity}"
  end
end  

summary = [Item.new("a", 1), Item.new("a", 2), Item.new("b", 5)].collapse {|a, b| a.quantity += b.quantity}
summary.collect(&:to_s) # => ["a - 3", "b - 5"]
A pretty flower Another pretty flower