1

与えられたハッシュ

z = [{'a' => 1, 'b' => 2}, {'a' => 3, 'b' => 4}, {'a' => 1, 'b' => 4}]

検索パラメータ自体がハッシュである場合、どのように検索しますか。

{'a' => 3}

z.find_by_hash({'a' => 3}) のようなことをして返すことができるように

{'a' => 3, 'b' => 4}

また、 z.find_by_hash({'a' => 1}) のような配列のコレクションを取得して返す

[{'a' => 1, 'b' => 2}, {'a' => 1, 'b => 4}]

ありがとう

4

4 に答える 4

1

あなたはこれを行うことができます:

class Array
  def find_by_hash(hash)
    self.select { |h| h.includes_hash?(hash) }
  end
end

class Hash
  def includes_hash?(other)
    included = true

    other.each do |key, value|
      included &= self[key] == other[key]
    end

    included
  end
end

これは、 aに別の (複数のキーと値を持つ) が含まHashれているかどうかを調べるメソッドによって拡張されます。必要な方法で拡張されていますが、これを行うことができるため、より一般的なアプローチです。HashArray

ary = [ {:a => 1, :b => 3, :c => 5}, {:a => 5, :b => 2, :c => 8} ]
ary.find_by_hash( { :a => 1, :c => 5 } )

注: Ruby では一般的な慣行であるSymbolため、キーに s を使用することも検討する必要がありますが、私のアプローチはキーでも機能します。Hash

于 2012-06-12T07:20:26.773 に答える
0

APIにアプローチが見つからなかったので、独自に実装する必要があると思います。
(ちなみに、@ megasのアプローチの方が優れていて読みやすいと思います)

TDDによるコード:

class SearchHashTest < Test::Unit::TestCase
  def setup
    @array_with_hash_elements = ArrayWithHashElements.new [{'a' => 1, 'b' => 2}, {'a' => 3, 'b' => 4}, {'a' => 1, 'b' => 4}]
  end
  def test_search_an_array_by_hash_parameter_and_return_single_hash
    assert_equal( {'a' => 3, 'b' => 4}, @array_with_hash_elements.search({'a'=>3}) )
  end
  def test_search_an_array_by_hash_parameter_and_return_an_array
    assert_equal( [{'a' => 1, 'b' => 2}, {'a'=> 1, 'b' => 4}], @array_with_hash_elements.search({'a'=>1}))
  end
end

実装されたコード(本番環境ではなく、デモ用)

class ArrayWithHashElements
  def initialize some_array
    @elements = some_array
  end
  def search( query_hash)
    puts "search:  #{query_hash.inspect}"
    result = []
    @elements.each do | array_element_in_hash_form|
      query_hash.each_pair do | key, value |
        if array_element_in_hash_form.has_key?(key) && array_element_in_hash_form[key] == value
          puts "adding : #{array_element_in_hash_form.inspect} to result"
          result << array_element_in_hash_form
        end
      end
      result
    end
    return result.size != 1 ? result : result[0]
  end
end

結果:

sg552@siwei-moto:~/workspace/test$ ruby search_hash_test.rb
Loaded suite search_hash_test
Started
search:  {"a"=>1}
adding : {"b"=>2, "a"=>1} to result
adding : {"b"=>4, "a"=>1} to result
.search:  {"a"=>3}
adding : {"b"=>4, "a"=>3} to result
.
Finished in 0.000513 seconds.

2 tests, 2 assertions, 0 failures, 0 errors
于 2012-06-12T07:15:30.883 に答える
0

基本的に必要なものは次のようなものです。

class Array
  def find_by_hash(h)
    h.collect_concat  do |key, value| 
      self.select{|h| h[key] == value}
    end
  end 
end
于 2012-06-12T07:11:06.337 に答える
0
z = [{'a' => 1, 'b' => 2}, {'a' => 3, 'b' => 4}, {'a' => 1, 'b' => 4}]

class Array
  def search_hash(hash)
    key = hash.keys.first
    value = hash.values.first
    select { |h| h[key] == value }
  end
end

z.search_hash({'a' => 3}) #=> [{"a"=>3, "b"=>4}]

または、中括弧なしで入力できます

z.search_hash('a' => 3)
于 2012-06-12T07:04:16.230 に答える