2

When I get an array of objects in JSON response, they might be represent in a different order.

Sometimes I get this

JSON.parse(response.body) # => [{"a" => "b"}, {"c" => "d"}]

or this

JSON.parse(response.body) # => [{"c" => "d"}, {"a" => "b"}]

But for me both results are correct. What is the easiest way to test which objects I have in response regardless of their order?

hs-
  • 1,016
  • 9
  • 17
  • 1
    possible duplicate of [Comparing ruby hashes](http://stackoverflow.com/questions/1766741/comparing-ruby-hashes) – KARASZI István Nov 05 '12 at 15:30
  • Do you want to compare the two or do you just want to check for the existence of certain keys? – Patrick Oscity Nov 05 '12 at 15:35
  • @padde, I want to compare two or more hashes in the array. But I don't want to compare their order in the array. – hs- Nov 05 '12 at 15:42
  • possible duplicate of [How do I compare two hashes?](http://stackoverflow.com/questions/4928789/how-do-i-compare-two-hashes) – ChrisF Nov 08 '12 at 13:40

2 Answers2

3

You can convert it into a set-like structure using a hash.

first_response.inject({}){|s, h| s[h] = true; s}

will be the same as

second_response.inject({}){|s, h| s[h] = true; s}
sawa
  • 165,429
  • 45
  • 277
  • 381
2

Along with its other useful features, the json spec gem has a be_json_eql matcher which works without respect to order.

zetetic
  • 47,184
  • 10
  • 111
  • 119
  • I'm not sure `be_json_eql` is order independent. The code looks like `@actual, @expected = scrub(actual_json, @path), scrub(@expected_json)` and then does a straight `@actual == @expected`. the `scrub` method is in charge of excluding keys you don't want to be part of the comparison (e.g. `updated_at`), and 'normalizing' the JSON, which just calls either `JSON.pretty_generate` or `to_json`. – chug2k Apr 04 '13 at 19:19