Estou tentando comparar dois Ruby Hashes usando o seguinte código:
#!/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
A saída para a tela é o arquivo completo do arquivo2. Sei com certeza que os arquivos são diferentes, mas o script não parece detectá-los.
Respostas:
Você pode comparar hashes diretamente para igualdade:
Você pode converter os hashes em matrizes e obter a diferença:
Simplificando ainda mais:
Atribuição de diferença por meio de uma estrutura ternária:
Fazer tudo em uma operação e se livrar da
difference
variável:fonte
hash1.to_a - hash3.to_a
ehash3.to_a - hash1.to_a
podem retornar valores não vazioshash1.size == hash3.size
. A parte após EDIT é válida apenas se os hashes forem de tamanhos diferentes..to_a
falhará quando os hashes iguais tiverem chaves em uma ordem diferente:{a:1, b:2} == {b:2, a:1}
=> verdadeiro,{a:1, b:2}.to_a == {b:2, a:1}.to_a
=> falsoflatten
e*
? Por que não apenasHash[A.to_a - B.to_a]
?Você pode tentar a gema hashdiff , que permite uma comparação profunda de hashes e matrizes no hash.
O seguinte é um exemplo:
fonte
got_hash.should eql expected_hash
porHashDiff.diff(got_hash, expected_hash).should eql []
, agora obtenho uma saída que mostra exatamente o que preciso. Perfeito!use_lcs: false
sinalizador pode acelerar significativamente as comparações em hashes grandes:Hashdiff.diff(b, a, use_lcs: false)
Se quiser saber qual é a diferença entre dois hashes, você pode fazer o seguinte:
fonte
Rails está descontinuando o
diff
método.Para uma linha rápida:
fonte
to_s
.{a:1, b:2} == {b:2, a:1}
=> true,{a:1, b:2}.to_s == {b:2, a:1}.to_s
=> falseVocê poderia usar uma interseção de matriz simples, dessa forma você pode saber o que difere em cada hash.
fonte
Eu tive o mesmo problema e enviei uma solicitação de pull para trilhos
https://github.com/elfassy/rails/commit/5f3410e04fe8c4d4745397db866c9633b80ccec6
fonte
Se você precisa de uma diferença rápida e suja entre os hashes que suporta corretamente nulo em valores você pode usar algo como
fonte
Se você quiser um diff bem formatado, pode fazer o seguinte:
E em seu código:
A ideia é usar uma impressão incrível para formatar e diferenciar a saída. O diff não será exato, mas é útil para fins de depuração.
fonte
... e agora na forma de módulo para ser aplicado a uma variedade de classes de coleção (Hash entre elas). Não é uma inspeção profunda, mas é simples.
fonte
Eu desenvolvi isso para comparar se dois hashes são iguais
O uso:
fonte
Isso foi respondido em " Comparando hashes de rubi ". O Rails adiciona um
diff
método aos hashes. Isso funciona bem.fonte
que tal converter o hash para_json e comparar como string? mas tendo em mente que
fonte
Aqui está um algoritmo para comparar profundamente dois Hashes, que também comparará matrizes aninhadas:
Implementação:
fonte
Que tal outra abordagem mais simples:
fonte