Array index inside map function

Hi all,

how can i access the index of the element inside the map argument block?

"101010,234,876".split(",").map {|c| get_something(c)}

this works. But the problem is i need to apply the get_something on only the
second and third element of the array. How can I check the index of the
element inside the map block?

Note :

I'm pretty new to ruby (just a month). So, this might be a pretty obvious
question.

- siddharth

Siddharth Venkatesan wrote in post #970728:

Hi all,

how can i access the index of the element inside the map argument block?

"101010,234,876".split(",").map {|c| get_something(c)}

this works. But the problem is i need to apply the get_something on only
the
second and third element of the array. How can I check the index of the
element inside the map block?

There is each_with_index, but that has the "each" functionality
and not the "map"/"collect" functionality.

That would be (not tested):
  result = []
  "101010,234,876".split(",").each_with_index {|c, i| result <<
do_something(c,i)}

HTH,

Peter

···

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

If you're using ruby 1.8.7 or later, calling each_with_index without a block
returns an enumerator, so that you can write something like:

"101010,234,876".split(",").each_with_index.map do |c, i|
  i == 1 or i == 2 ? get_something(c) : c
end

I hope this helps

Stefano

···

On Sunday 26 December 2010 17:47:19 Peter Vandenabeele wrote:

Siddharth Venkatesan wrote in post #970728:
> Hi all,
>
> how can i access the index of the element inside the map argument block?
>
> "101010,234,876".split(",").map {|c| get_something(c)}
>
> this works. But the problem is i need to apply the get_something on only
> the
> second and third element of the array. How can I check the index of the
> element inside the map block?

There is each_with_index, but that has the "each" functionality
and not the "map"/"collect" functionality.

That would be (not tested):
  result = []
  "101010,234,876".split(",").each_with_index {|c, i| result <<
do_something(c,i)}

HTH,

Peter

(2010/12/26 17:47), Peter Vandenabeele wrote:

There is each_with_index, but that has the "each" functionality
and not the "map"/"collect" functionality.

Why not use Ruby 1.9?

irb(main):001:0> ["x", "y", "z"].map.with_index {|i, j| [i, j] }
=> [["x", 0], ["y", 1], ["z", 2]]

Thanks a lot.

All of the three solution taught me something. I think i'll go with
.map.with_index. That looks concise.

Thanks again.

You can make this work in 1.8.7 too:

["x","y","z"].each_with_index.map { |x| x }

=> [["x", 0], ["y", 1], ["z", 2]]

···

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

There is also the slightly less concise and elegant but possibly
somewhat faster:
ii = -1; "101010,234,876".split(",").map {|c| ii += 1; get_something(c)}

                                                user system total real
Ruby: version=1.9.1; platform=i486-linux;

  ary1 = ary.map.with_index { |e, i| 355 } 2.780 0.000 2.780 ( 2.787)
  j = -1; ary2 = ary.map { |e| j += 1; 113 } 2.550 0.010 2.560 ( 2.556)

  ary3 = ari.map!.with_index { |e, i| 355 } 2.590 0.000 2.590 ( 2.591)
  j = -1; ary4 = arj.map! { |e| j += 1; 113 } 2.150 0.000 2.150 ( 2.150)

Ruby: version=1.9.1; platform=i386-mingw32;

  ary1 = ary.map.with_index { |e, i| 355 } 2.870 0.000 2.870 ( 2.893)
  j = -1; ary2 = ary.map { |e| j += 1; 113 } 2.028 0.016 2.044 ( 2.045)

  ary3 = ari.map!.with_index { |e, i| 355 } 2.761 0.000 2.761 ( 2.772)
  j = -1; ary4 = arj.map! { |e| j += 1; 113 } 1.997 0.000 1.997 ( 2.008)

*** code for benchmarks

class Array # so we can tell if same array and see changes
  def ps( name = '?' )
    puts "#{name}: <oid=#{object_id}: [0] = #{self[0].inspect}>"
  end
end

require "benchmark"
kt = 100_000
nn = 100
ary = Array.new( nn, 42 )
ari = Array.new( nn, 22 ); arj = Array.new( nn, 7 )
puts
puts "Ruby: version=#{RUBY_VERSION}; platform=#{RUBY_PLATFORM};"
puts
ary.ps('ary'); ari.ps('ari'); arj.ps('arj')
puts
ary1 = ary2 = ary3 = ary4 = nil
w = 50
Benchmark.bmbm( w ) do |bm|
  bm.report( "ary1 = ary.map.with_index { |e, i| 355 }" ) {
   kt.times { ary1 = ary.map.with_index { |e, i| 355 } } }
  bm.report( "j = -1; ary2 = ary.map { |e| j += 1; 113 }" ) {
   kt.times { j = -1; ary2 = ary.map { |e| j += 1; 113 } } }
  bm.report( "ary3 = ari.map!.with_index { |e, i| 355 }" ) {
   kt.times { ary3 = ari.map!.with_index { |e, i| 355 } } }
  bm.report( "j = -1; ary4 = arj.map! { |e| j += 1; 113 }" ) {
   kt.times { j = -1; ary4 = arj.map! { |e| j += 1; 113 } } }
end
puts
ary.ps('ary'); ari.ps('ari'); arj.ps('arj')
puts
ary1.ps('ary1'); ary2.ps('ary2'); ary3.ps('ary3'); ary4.ps('ary4')

···

On Sun, Dec 26, 2010 at 8:34 AM, Siddharth Venkatesan <neotamizhan@gmail.com> wrote:

how can i access the index of the element inside the map argument block?
  "101010,234,876".split(",").map {|c| get_something(c)}
...

On Sun, Dec 26, 2010 at 9:13 AM, Siddharth Venkatesan <neotamizhan@gmail.com> wrote:

All of the three solution taught me something. I think i'll go with .map.with_index.
That looks concise.

Frankly, I would do something different:

input = "101010,234,876"
# ...
junk, a, b, *remainder = input.split ','

get_something a
get_something b

Kind regards

robert

···

On Sun, Dec 26, 2010 at 10:13 AM, Siddharth Venkatesan <neotamizhan@gmail.com> wrote:

All of the three solution taught me something. I think i'll go with
.map.with_index. That looks concise.

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

"101010,234,876".split(",").drop(1).map{|c| get_something(c)}

···

On Dec 27, 4:42 am, Robert Klemme <shortcut...@googlemail.com> wrote:

On Sun, Dec 26, 2010 at 10:13 AM, Siddharth Venkatesan > > <neotamiz...@gmail.com> wrote:
> All of the three solution taught me something. I think i'll go with
> .map.with_index. That looks concise.

Frankly, I would do something different:

input = "101010,234,876"
# ...
junk, a, b, *remainder = input.split ','

get_something a
get_something b

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/