Reputation: 15374
If I have the following hash and array
hash = {'i' => 'i', 'av' => 'av', 'deviceName' => 'Genymotionvbox86p'}
array = ['i', 'av', 'Genymotionvbox86p']
How could I compare that each item in the array matches the hashes value in the same order
So far I have
array.each do |value|
hash.each do |k, v|
expect(v).to eq(value), "expected #{k} to equal #{v}, instead got #{value}"
end
end
This is failing as I get
expected av to equal av, instead got i (RSpec::Expectations::ExpectationNotMetError)
I'm not quite there yet and imagine that a loop within a loop is not the best thing to do either?
I would like to know how to efficiently approach this.
Upvotes: 0
Views: 89
Reputation: 10251
How could I compare that each item in the array matches the hashes value in the same order
how about this?
> array == hash.values
#=> true
> array = ["i", "Genymotionvbox86p", "av"] # change the order
> array == hash.values
#=> false
Upvotes: 0
Reputation: 36100
The reason this fails is because you compare every array value with every hash value. To solve this, you can take advantage of the fact that two arrays arrays are equal if all their values in order are equal:
expect(array).to eq hash.values
Upvotes: 5
Reputation: 44080
If you would really want to compare item-by-item, you rightfully noticed that a loop within a loop is not the way to go. You need a single loop to iterate both structures.
For that, you can, for example, use zip
, to combine hash and array:
hash.zip(array).each do |(hash_key, hash_value), array_item|
expect(hash_value).to eq array_item
end
or you can resort to using an index:
hash.each_with_index do |(k, v), i|
expect(v).to eq array[i]
end
Upvotes: 1