Hash#map_pairs

class Hash
   def map_pairs
      result = Array.new
      self.each_pair { |k, v|
         result << yield(k, v)
      }
      result
   end
end

h = {
   "a" => "x",
   "b" => "y",
}
puts h.map_pairs { |k, v| "#{k} => #{v}" }.join(", ")

I was surprised to discover there was no Hash#map_pairs. I have found
that chaining transformations is usually better than the
iterative/imperative style implied by Hash#each_pair.

On second thought, it looks like this does the same thing:

puts h.to_a.map { |k, v| "#{k} => #{v}" }.join(", ")

But this fails to convey the programmer's idea in the same way that
map_pairs does. It is also needlessly inefficient, using a whole
extra temp array.

harp:~ > cat a.rb
class Hash
   def map_pairs
      result = Array.new
      self.each_pair { |k, v|
         result << yield(k, v)
      }
      result
   end
end

h = {
   "a" => "x",
   "b" => "y",
}

puts h.map_pairs { |k, v| "#{k} => #{v}" }.join(", ")
puts h.map{ |k, v| "#{k} => #{v}" }.join(", ") ### :wink:

harp:~ > ruby a.rb
a => x, b => y

-a

···

On Sun, 25 Mar 2007 jeff_alexander_44@yahoo.com wrote:

class Hash
  def map_pairs
     result = Array.new
     self.each_pair { |k, v|
        result << yield(k, v)
     }
     result
  end
end

h = {
  "a" => "x",
  "b" => "y",
}
puts h.map_pairs { |k, v| "#{k} => #{v}" }.join(", ")

I was surprised to discover there was no Hash#map_pairs. I have found
that chaining transformations is usually better than the
iterative/imperative style implied by Hash#each_pair.

On second thought, it looks like this does the same thing:

puts h.to_a.map { |k, v| "#{k} => #{v}" }.join(", ")

But this fails to convey the programmer's idea in the same way that
map_pairs does. It is also needlessly inefficient, using a whole
extra temp array.

--
be kind whenever possible... it is always possible.
- the dalai lama

In Ruby 1.9 , at least as it stands today, 'each-like' methods like
each_pair will return an Enumerator if you don't give them a block,
this allows a nice ability to chain transformations.

rick@frodo:/public/rubysource/ruby1.8.5$ irb1.9
irb(main):001:0> {:a => 1, :b => 2}.each_pair
=> #<Enumerable::Enumerator:0xb7bd2650>
irb(main):002:0> {:a => 1, :b => 2}.each_pair.map {|k,v| [v,k]}
=> [[2, :b], [1, :a]]
irb(main):003:0>

···

On 3/24/07, jeff_alexander_44@yahoo.com <jeff_alexander_44@yahoo.com> wrote:

class Hash
   def map_pairs
      result = Array.new
      self.each_pair { |k, v|
         result << yield(k, v)
      }
      result
   end
end

h = {
   "a" => "x",
   "b" => "y",
}
puts h.map_pairs { |k, v| "#{k} => #{v}" }.join(", ")

I was surprised to discover there was no Hash#map_pairs. I have found
that chaining transformations is usually better than the
iterative/imperative style implied by Hash#each_pair.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

I've been looking at this of late,

what I want is ;

class Hash
  def map_pairs
    new_hash = self.class.new # works in HashWithIndifferentAccess
    self.each do |key, value|
      new_key, new_value = yield(key, value)
      new_hash[new_key] = new_value
    end
    return new_hash
  end

  def map_values
    new_hash = self.class.new
    self.each do |key, value|
      new_hash[key] = yield(key, value)
    end
    return new_hash
  end
end

is that a bad idea?
does "map" have to return an array?

···

--
Posted via http://www.ruby-forum.com/.

Aha, thanks.

I was fooled by ri's output. My eyes went straight to the "Instance
methods" section. Since "map" is an instance method, shouldn't it be
listed under "Instance methods"? I now see that it's listed under
"Includes" --- which is fine, in addition to "Instance methods".

It is mixed in from the Enumerable module. It has lots of cool
functions. You should check it out, since Hash has them all as well
as Array.

···

On 3/24/07, jeff_alexander_44@yahoo.com <jeff_alexander_44@yahoo.com> wrote:

Aha, thanks.

I was fooled by ri's output. My eyes went straight to the "Instance
methods" section. Since "map" is an instance method, shouldn't it be
listed under "Instance methods"? I now see that it's listed under
"Includes" --- which is fine, in addition to "Instance methods".

--
Chris Carter
concentrationstudios.com
brynmawrcs.com

it's mixed in from enumerable - in fact the impl is much like you rolled on
your own. there are a ton of useful methods from enumerable implemented in
terms of #each. i suppose it's debatable where the docs should appear but i
personally think it's best to be clear and doccument them in enumerable where
they are defined.

cheers.

-a

···

On Sun, 25 Mar 2007 jeff_alexander_44@yahoo.com wrote:

Aha, thanks.

I was fooled by ri's output. My eyes went straight to the "Instance
methods" section. Since "map" is an instance method, shouldn't it be
listed under "Instance methods"? I now see that it's listed under
"Includes" --- which is fine, in addition to "Instance methods".

--
be kind whenever possible... it is always possible.
- the dalai lama

$ irb
irb(main):001:0> Hash.instance_methods.include? "map"
=> true

So one would expect "map" to appear under "Instance methods" in ri.
Of course it comes from a mixin. That's not the issue here. The
existence of this thread is a data point.

Thus ensues the eternal struggle between those who are accustomed to
the idiosyncrasies and those who are driven insane by them.

ruby is a dangerous place to be if that sort of thing drives a fellow insane:

   harp:~ > irb -r ostruct

   irb(main):001:0> os = OpenStruct.new
   => #<OpenStruct>

   irb(main):002:0> os.methods.grep /foobar/
   =>

   irb(main):003:0> os.foobar = 42
   => 42

   irb(main):004:0> os.foobar
   => 42

-a

···

On Sun, 25 Mar 2007 jeff_alexander_44@yahoo.com wrote:

$ irb
irb(main):001:0> Hash.instance_methods.include? "map"
=> true

So one would expect "map" to appear under "Instance methods" in ri.
Of course it comes from a mixin. That's not the issue here. The
existence of this thread is a data point.

Thus ensues the eternal struggle between those who are accustomed to
the idiosyncrasies and those who are driven insane by them.

--
be kind whenever possible... it is always possible.
- the dalai lama

Person A: "Here is a needless idiosyncrasy: ..."
Person B: "I can produce apparent idiosyncratic behavior with
method_missing."
Person A: "Well, of course. But what about the idiosyncrasy I
mentioned?"

The struggle continues...