LoginSignup
9
7

More than 5 years have passed since last update.

配列の指定した文字列と部分一致する要素のindexを全て配列で返すメソッド

Last updated at Posted at 2015-06-27
arr = ["オレンジジュース", "トマト缶", "ナタデココ缶", "リンゴジュース", "バナナオレ"]
arr.which_elements_is_include("ジュース")
=> [0, 3]

なメソッドが欲しかった。

class Array
  def which_elements_is_include(value)
    self.map.with_index{|item, i| i if item.include?(value)}.compact
  end
end

追記 その2

@jnchitoさんがとても便利なメソッドを作ってくださいました。ありがとうございます。

index_select(Array)-created_by_@jnchito
class Array
  def index_select(obj = nil)
    if obj.nil? && !block_given?
      self.each
    else
      proc = obj.nil? ? ->(i){ yield self[i] } : ->(i){ self[i] == obj }
      self.each_index.select(&proc)
    end
  end
end

動作確認用のテストも作ってくださいました。

単体テスト-created_by_@jnchito
require 'test/unit'
class TestIndexSelect < Test::Unit::TestCase
  def test_index_select
    arr1 = [100, 200, 100, 300, 100, 400]
    result1 = arr1.index_select(100)
    assert_equal [0, 2, 4], result1

    arr2 = ["ととろ", "まっくろくろすけ", "ととろ", "めいちゃん", "さつきちゃん", "ととろ"]
    result2 = arr2.index_select("ととろ")
    assert_equal [0, 2, 5], result2

    arr3 = ["オレンジジュース", "トマト缶", "ナタデココ缶", "リンゴジュース", "バナナオレ"]
    result3 = arr3.index_select {|v| v =~ /ジュース/}
    assert_equal [0, 3], result3

    # 両方渡した場合
    arr4 = [100, 200, 100, 300, 100, 400]
    result4 = arr4.index_select(100) {|v| v == 200}
    assert_equal [0, 2, 4], result4

    # どちらも渡さない場合
    arr5 = [100, 200, 100, 300, 100, 400]
    result5 = arr5.index_select
    assert result5.is_a?(Enumerator)
    assert_equal arr5, result5.to_a
  end
end

仕様

array.index_select(obj) -> Array | nil

追記

コメントで教えていただいた@pocariさんのRuby - find_allのindex版 - Qiitaのほうが柔軟で汎用的なので今後はこちらを使うことにします。
ありがとうございます。

9
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7