inject

ways to use #inject

sum an array

[0,1,2,3].inject(0){|sum, i| sum+i}
#=> 6

——————>>>>>>——————

linear array into hash

["apple", "orange", "pineapple"].inject({}){|k, v| k[v]=1; k} 
#=> {"apple"=>1, "orange"=>1, "pineapple"=>1} 

k: {}
v: apple
k: {“apple”=>1}
v: orange
k: {“apple”=>1, “orange”=>1}
v: pineapple
=> {“apple”=>1, “orange”=>1, “pineapple”=>1}

check this out

fruits = ["apple", "orange", "pineapple", "apple"]
fruits.inject(Hash.new(0)){|k, v| k[v]+=1; k} 
 #=> {"apple"=>2, "orange"=>1, "pineapple"=>1} 

or use #update

[0,1,2,3].inject({}) {|result, i| result.update(i => i+1)}
#=> {0=>1, 1=>2, 2=>3, 3=>4} 

k: {}
v: 0
k: {0=>1}
v: 1
k: {0=>1, 1=>2}
v: 2
k: {0=>1, 1=>2, 2=>3}
v: 3
=> {0=>1, 1=>2, 2=>3, 3=>4}

notice the difference in these two and the importance- make sure a hash is returned.

——————>>>>>>——————

arrays into hash

 def array_to_hash(array)
   array.inject({}) do |result, element|
     result[element.first] = element.last
     result
   end
 end

a = [[:fruit, "apple"],[:taste, "good"]]
array_to_hash(a)
#=> {:fruit=>"apple", :taste=>"good"} 

sidenote: or use Hash and group the arrays

Hash[*[[:fruit, "apple"],[:taste, "good"]].flatten]
#=> {:fruit=>"apple", :taste=>"good"} 

or this… dudh

[[:fruit, "apple"], [:taste, "good"]].to_h
#=> {:fruit=>"apple", :taste=>"good"} 

——————>>>>>>——————

turn hash into array

h = {0=>1, 1=>2, 2=>3, 3=>4}
h.inject([]){|result, i| p result; p i; result<<i}
#=> [[0, 1], [1, 2], [2, 3], [3, 4]] 

or this… dudh no.2

h.to_a
#=> [[0, 1], [1, 2], [2, 3], [3, 4]] 

——————>>>>>>——————

swap keys and values in hash

braces = {"[" => "]", "(" => ")", "{" => "}"}
braces.inject({}){|result, (k,v)| result[v]=k; result}
# => {"]"=>"[", ")"=>"(", "}"=>"{"} 

or invert

braces.invert
# => {"]"=>"[", ")"=>"(", "}"=>"{"} 

but both are lossy, if there’re multiple of the same values, then only the last value will be saved… this is where each_with_object comes in handy.

s = {:a=>1, :b=>2, :c=>2} 
s.each_with_object({}){|(k,v), result| result[v] ||=[]; result[v] << k }
# => {1=>[:a], 2=>[:b, :c]} 

these are only some basic usage, but hopefully you get the gist to use it to your advantages.