如何比较关于元素顺序的两个多维散列

问题描述 投票:0回答:1

我陷入了这样的问题。我有2个哈希,我想在rspec测试中进行比较:

describe 'sort tests' do
  let(:actual) do
    {
      1 => { users: { 1 => { id: 1,
                             accounts: [1],
                             profit: 10,
                             revenue: 1,
                             loss: 9 },
                      2 => { id: 2,
                             accounts: [2, 3, 6],
                             profit: -24,
                             revenue: 6,
                             loss: -30 } },
             total_profit: -14,
             total_revenue: 7,
             total_loss: -21 },
      2 => { users: { 3 => { id: 3,
                             accounts: [4, 5],
                             profit: 27,
                             revenue: 9,
                             loss: 18 } },
             total_profit: 27,
             total_revenue: 9,
             total_loss: 18 }
    }
  end
  let(:expected) do
    {
      1 => { users: { 2 => { id: 2,
                             accounts: [2, 3, 6],
                             profit: -24,
                             revenue: 6,
                             loss: -30 },
                      1 => { id: 1,
                             accounts: [1],
                             profit: 10,
                             revenue: 1,
                             loss: 9 } },
             total_profit: -14,
             total_revenue: 7,
             total_loss: -21 },
      2 => { users: { 3 => { id: 3,
                             accounts: [4, 5],
                             profit: 27,
                             revenue: 9,
                             loss: 18 } },
             total_profit: 27,
             total_revenue: 9,
             total_loss: 18 }
    }
  end

  it 'sort' do
    def mysort(data)
      data.each do |_, partner|
        partner[:users].sort_by { |_k, user| user[:loss] }.to_h
        partner
      end
      data.sort_by { |_, partner| partner[:total_loss] }.to_h
    end
    expect(mysort(actual)).to eql expected
    # expect(Digest::MD5.hexdigest(Marshal::dump(mysort(actual)))).to eql Digest::MD5.hexdigest(Marshal::dump(expected))
  end
end

测试通过。但是,如果我取消对md5检查的注释,它将引发一个哈希不同的错误:

expected: "155d27d209f286fb1fc9ebeb0dcd6d3d"
     got: "255df98d4fc8166d0d8ffc7227ffd351"

因此,eql实际上没有正确比较散列,并且mysort函数中存在错误:

def mysort(data)
  data.each do |_, partner|
    partner[:users] = partner[:users].sort_by { |_k, user| user[:loss] }.to_h
    partner
  end
  data.sort_by { |_, partner| partner[:total_loss] }.to_h
end

现在可以排序了,但是仅比较md5校验和有助于了解哈希是否相等:(

如何在没有这种技巧的情况下比较散列?

ruby multidimensional-array hash rspec
1个回答
0
投票

如果您不想使用md5并且具有深层嵌套的哈希,则需要一个递归比较器。

compare =
  -> (h1, h2) do
    h1 == h2 && # leave only different order possibility
      (
        !h1.is_a?(Hash) || # leaves

        h1.keys == h2.keys && # check order
        h1.all? { |k, v| compare.(v, h2[k]) } # check nested hashes
      )
  end

现在只需调用compare.(h1, h2),对于相同的哈希,它将返回true,否则返回false

© www.soinside.com 2019 - 2024. All rights reserved.