[ruby] 두 해시를 어떻게 비교합니까?

다음 코드를 사용하여 두 개의 Ruby Hashe를 비교하려고합니다.

#!/usr/bin/env ruby

require "yaml"
require "active_support"

file1 = YAML::load(File.open('./en_20110207.yml'))
file2 = YAML::load(File.open('./locales/en.yml'))

arr = []

file1.select { |k,v|
  file2.select { |k2, v2|
    arr << "#{v2}" if "#{v}" != "#{v2}"
  }
}

puts arr

화면 출력은 file2의 전체 파일입니다. 나는 파일이 다르다는 사실을 알고 있지만 스크립트가 그것을 선택하지 않는 것 같습니다.



답변

해시를 직접 비교할 수 있습니다.

hash1 = {'a' => 1, 'b' => 2}
hash2 = {'a' => 1, 'b' => 2}
hash3 = {'a' => 1, 'b' => 2, 'c' => 3}

hash1 == hash2 # => true
hash1 == hash3 # => false

hash1.to_a == hash2.to_a # => true
hash1.to_a == hash3.to_a # => false


해시를 배열로 변환 한 다음 그 차이를 얻을 수 있습니다.

hash3.to_a - hash1.to_a # => [["c", 3]]

if (hash3.size > hash1.size)
  difference = hash3.to_a - hash1.to_a
else
  difference = hash1.to_a - hash3.to_a
end
Hash[*difference.flatten] # => {"c"=>3}

추가 단순화 :

삼항 구조를 통해 차이 할당 :

  difference = (hash3.size > hash1.size) \
                ? hash3.to_a - hash1.to_a \
                : hash1.to_a - hash3.to_a
=> [["c", 3]]
  Hash[*difference.flatten] 
=> {"c"=>3}

한 번의 작업으로 모든 작업을 수행하고 difference변수를 제거 합니다.

  Hash[*(
  (hash3.size > hash1.size)    \
      ? hash3.to_a - hash1.to_a \
      : hash1.to_a - hash3.to_a
  ).flatten] 
=> {"c"=>3}


답변

해시의 해시와 배열을 자세히 비교할 수 있는 hashdiff gem을 사용해 볼 수 있습니다 .

다음은 그 예입니다.

a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}}
b = {a:{y:3}, b:{y:3, z:30}}

diff = HashDiff.diff(a, b)
diff.should == [['-', 'a.x', 2], ['-', 'a.z', 4], ['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]


답변

두 해시의 차이점을 얻으려면 다음을 수행하십시오.

h1 = {:a => 20, :b => 10, :c => 44}
h2 = {:a => 2, :b => 10, :c => "44"}
result = {}
h1.each {|k, v| result[k] = h2[k] if h2[k] != v }
p result #=> {:a => 2, :c => "44"}


답변

Rails는 이 메소드를 더 이상 사용하지 않습니다diff .

빠른 한 줄짜리 :

hash1.to_s == hash2.to_s


답변

간단한 배열 교차를 사용하면 각 해시의 차이점을 알 수 있습니다.

    hash1 = { a: 1 , b: 2 }
    hash2 = { a: 2 , b: 2 }

    overlapping_elements = hash1.to_a & hash2.to_a

    exclusive_elements_from_hash1 = hash1.to_a - overlapping_elements
    exclusive_elements_from_hash2 = hash2.to_a - overlapping_elements


답변

나는 같은 문제가 있었고 레일에 풀 요청을 보냈습니다.

  • 깊이 중첩 된 해시와 함께 작동
  • 해시 배열과 함께 작동

https://github.com/elfassy/rails/commit/5f3410e04fe8c4d4745397db866c9633b80ccec6


답변

값에서 nil을 올바르게 지원하는 해시 간의 빠르고 더러운 diff가 필요하면 다음과 같은 것을 사용할 수 있습니다.

def diff(one, other)
  (one.keys + other.keys).uniq.inject({}) do |memo, key|
    unless one.key?(key) && other.key?(key) && one[key] == other[key]
      memo[key] = [one.key?(key) ? one[key] : :_no_key, other.key?(key) ? other[key] : :_no_key]
    end
    memo
  end
end