Rubyでインデックスにマップする方法は?


回答:


835

あなたはルビー1.8.7または1.9を使用している場合は、イテレータの方法が好きという事実を使用することができeach_with_index、ブロックせずに呼び出されたときに、返すEnumeratorあなたが呼び出すことができるオブジェクト、Enumerableなどの方法mapでは。だからあなたはできる:

arr.each_with_index.map { |x,i| [x, i+2] }

1.8.6では次のことができます。

require 'enumerator'
arr.enum_for(:each_with_index).map { |x,i| [x, i+2] }

ありがとう!のドキュメントへのポインタを教えていただけます.each_with_index.mapか?
Misha Moroshko、2011年

1
@Misha:いつものmap方法ですEnumerableeach_with_index返し、ブロックせずに呼び出されたときEnumeratorにどのミックス、(1.8.7+に)オブジェクトをEnumerable呼び出すことができますので、mapselectrejectちょうどアレイ上、ハッシュ、範囲などのように、その上など
sepp2k

9
IMOこれは1.8.7+でより読みやすくなりました:arr.map.with_index{ |o,i| [o,i+2] }
Phrogz

4
@Phrogz:map.with_index1.8.7では機能しません(map1.8でブロックなしで呼び出されると配列を返します)。
sepp2k 2011年

2
これは.mapでは機能しないことに注意してください!ループしている配列に直接影響を与えたい場合。
アッシュブルー


130

ruby 1.9.3には、with_index連鎖してマップできるメソッドが呼び出されます。

例えば:

array.map.with_index { |item, index| ... }

17

上位の難読化:

arr = ('a'..'g').to_a
indexes = arr.each_index.map(&2.method(:+))
arr.zip(indexes)

12
アンドリューは素晴らしい仕事の安全性を持っているに違いありません!:)
David J.

9

次に、列挙子を使用しない1.8.6(または1.9)の2つのオプションを示します。

# Fun with functional
arr = ('a'..'g').to_a
arr.zip( (2..(arr.length+2)).to_a )
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]

# The simplest
n = 1
arr.map{ |c| [c, n+=1 ] }
#=> [["a", 2], ["b", 3], ["c", 4], ["d", 5], ["e", 6], ["f", 7], ["g", 8]]


4

これを行うには楽しいが役に立たない方法:

az  = ('a'..'z').to_a
azz = az.map{|e| [e, az.index(e)+2]}

なぜ嫌い?これは機能的な方法であり、結果を達成するための愚かな方法でもあります。
Automatico、

#indexの呼び出しは、これがO(N ^ 2)ループであることを意味し、なぜ+2ですか?:)
rogerdpack 2017年

2
私が書いているようにA fun, but useless way+2OPが要求する出力を作成すること
Automatico


1
module Enumerable
  def map_with_index(&block)
    i = 0
    self.map { |val|
      val = block.call(val, i)
      i += 1
      val
    }
  end
end

["foo", "bar"].map_with_index {|item, index| [item, index] } => [["foo", 0], ["bar", 1]]

3
ああ、神様!他の答えも読みましたか?map.with_indexルビーにはすでに存在します。列挙可能なクラスを再度開いて、すでに存在するものを追加することを提案するのはなぜですか?
nathanvda 2014年

これは、1.8.6と1.8.7に進むためのより簡単な方法かもしれません(はい、私たちの一部はまだそれを使用しています)each_with_index.map。 map.with_index FWIW :)
rogerdpack 2017年

1

私はよくこれをします:

arr = ["a", "b", "c"]

(0...arr.length).map do |int|
  [arr[int], int + 2]
end

#=> [["a", 2], ["b", 3], ["c", 4]]

配列の要素を直接反復処理する代わりに、整数の範囲を反復処理し、それらをインデックスとして使用して配列の要素を取得します。


1
他の答えを読んだら、もっと良い方法があることに気づいてほしい。なぜこれを追加する必要があるのか​​わからない。
nathanvda 2014年

アンドリューグリムの答えが10票に値する場合、これは少なくとも1票に値します!
Camille Goudeseune
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.