Search code examples
ruby

Ruby - map vs each?


I have this code of mine:

def yeller(array)
  a = array.each(&:upcase)
  puts a
  puts array
  return "a: " + a.join
  return "array: " + array.join
end

yeller(%w[a, b, c]) # => "a: a,b,c"
# >> a,
# >> b,
# >> c
# >> a,
# >> b,
# >> c

def yeller(array)
  a = array.map(&:upcase)
  puts a
  puts array
  return "a: " + a.join
  return "array: " + array.join
end

yeller(%w[a, b, c]) # => "a: A,B,C"
# >> A,
# >> B,
# >> C
# >> a,
# >> b,
# >> c

What is confusing, is that array disappeared. Where is it? What is the difference between each and map?

Please, someone more familiar with Ruby come and correct me: I understand map iterates the array and returns an array, while each iterates only.


Solution

  • The doc suggests:

    each { |item| block } → ary click to toggle source each → Enumerator Calls the given block once for each element in self, passing that element as a parameter.

    And:

    map { |item| block } → new_ary click to toggle source map → Enumerator Invokes the given block once for each element of self.

    Creates a new array containing the values returned by the block.

    See also Enumerable#collect.

    If no block is given, an Enumerator is returned instead.

    which actually means that map creates another new array while each simply iterates and does not touch the original array.

    An example:

    def yeller(array)
     a = array.each(&:upcase)
     puts a
     puts array
     puts "a: " + a.join
     puts "array: " + array.join
     puts "a == array?" + (a==array).to_s
    end
    
    yeller(%w[a, b, c])
    
    def yeller(array)
      a = array.map(&:upcase)
      puts a
      puts array
      puts "a: " + a.join
      puts "array: " + array.join
    end
    
    yeller(%w[a, b, c])
    

    Result:

    a,
    b,
    c
    a,
    b,
    c
    a: a,b,c
    array: a,b,c
    a == array?true
    A,
    B,
    C
    a,
    b,
    c
    a: A,B,C
    array: a,b,c