2012-06-11 7 views
5

列挙型オブジェクトenumがあり、今度は3番目のアイテムを取得したいとします。は、指定されたインデックスを持つ列挙子の値を参照します。

私は一般的なアプローチの一つは、配列に変換してからのようなインデックスを使用してアクセスを知っている:

enum.to_a[2] 

しかし、この方法は、一時的な配列を作成し、それは非効率的であるかもしれません。

今、私が使用します。

enum.each_with_index {|v, i| break v if i == 2} 

しかし、これは非常に醜いと冗長です。

これを行う最も効率的な方法は何ですか?

答えて

5

あなたはtakeがあなたに与えること配列から三番目の要素をつかむために最初の3つの要素と、その後lastを剥離しtakeを使用することができます。

third = enum.take(3).last 

をあなたがまったくの配列を生成したくない場合をおそらく:

# If enum isn't an Enumerator then 'enum = enum.to_enum' or 'enum = enum.each' 
# to make it one. 
(3 - 1).times { enum.next } 
third = enum.next 
+0

これは良く見えるが、私は指標として非常に大きな数をしたい場合、それはまだそれのために非常に大きな一時的な配列を生成します。 –

+0

@ShouYa:あなたがコメントしている間、別の配列なしオプションを追加しました。 'enum'を1つずつチェックする必要がありますが、それについては何もできません(一般的に)。 –

+0

次は、スマートな提案です。私は、パフォーマンスの意味がコレクションを配列に変換することと比べてどのようなものかを知ることは興味があります。 –

1

は残念ながら、インデックスでメンバにアクセスするには、(そうでない場合、あなたが最初の場所でインデックスを持っていません)配列に変換する必要があるので、あなたのコードは、私には完全に正常に見えます。

+0

うーん、いいえ。 'e'が' Enumerator'ならば、 '2times {e.next}'は最初の2つの値を捨てて、3番目の 'e.next'は配列を生成せずに3番目の値を返します。 –

+0

@muistooshort yep、あなたのスレッドに返信しました。そして、あなたはその点で正しいです。 –

5

enumerable-lazyまたはRuby 2.1を使用したmuの回答に代わるものです。 nextを使用しますが、はるか宣言型のように怠惰:

enum.lazy.drop(2).first 
関連する問題