This question already has an answer here:
-
How to implement injection in Ruby?
1 answer
I have a class called Hsh which basically simulates a hash. It has an array of Couple objects (which hold fields named one and two, one is an int another is a string name of that int).
I am supposed to be able to accept the following call:
h = x.inject({}) {|a, b| a[b.one] = b.two; a}
Where x is the Hsh object.
I am not sure how to implement the inject method within Hsh? Like, what would I write in:
def inject ????
??
??
end
All it's supposed to do is create a hash map.
require 'ostruct'
class Hsh
include Enumerable
def initialize
@arr = (0..9).map{ |i| OpenStruct.new(:one => i, :two => "#{i}")}
end
def each(&block)
@arr.each(&block)
end
end
p Hsh.new.inject({}) {|a, b| a[b.one] = b.two; a}
#=> {5=>"5", 0=>"0", 6=>"6", 1=>"1", 7=>"7", 2=>"2", 8=>"8", 3=>"3", 9=>"9", 4=>"4"}
In this particular case Hsh
is actually an array, so unless you use it for something else such a complex code doesn't make sense, it can be done much easier:
p (0..9).map{ |i| OpenStruct.new(:one => i, :two => "#{i}")} \
.inject({}) {|a, b| a[b.one] = b.two; a}
#=> {5=>"5", 0=>"0", 6=>"6", 1=>"1", 7=>"7", 2=>"2", 8=>"8", 3=>"3", 9=>"9", 4=>"4"}
you shouldn't really need to implement it, just implement Hsh#each
and include Enumerable
, you'll get inject
for free.
For your specific example something like this should work:
def inject accumulator
#I assume Hsh has some way to iterate over the elements
each do |elem|
accumulator = yield accumulator, elem
end
accumulator
end
But the real implementation of inject is a bit different (e.g. works without providing an accumulator, takes a symbol instead of a block etc)
I have used OpenStruct instead of classes. See if this works for you
require 'ostruct'
class Hsh
attr_accessor :arr
def initialize
obj = OpenStruct.new
obj.one = 1
obj.two = "two"
@arr = [obj]
end
def inject(hash)
@arr.each do |arr|
yield hash, arr
end
hash
end
end
x = Hsh.new
p x.inject({}) {|a, b| a[b.one] = b.two} #prints {1 => "two"}