#ruby #rspec
#ruby #rspec
Вопрос:
Существует ли какая-либо ожидаемая спецификация, которая будет сравнивать два хэша, исключая только указанные ключи.
H1 = {'name' => 'XXXXx', 'age' => 29, 'DOB' => 'dd/mm/yyyy'}
H2 = {'name' => 'XXXXX', 'age' => 29, 'DOB' => 'dd/mm/yyyy'}
Сравните два вышеупомянутых хэша, исключив только ключ DOB.
Комментарии:
1.
Hash#values_at
иmatch_array
ожидание?2. values_at вернет массив значений, основанный на ключах, указанных в values_at. Но я хочу исключить только определенный набор ключей
3.
Hash#reject
затем.4. Имена разные (
"XXXXX"
и"XXXXx"
)? Или это опечатка?5. Нет, это обдумано. Отныне я должен получить результат, поскольку имя отличается на H2 при сравнении с H1
Ответ №1:
Я не понимаю, зачем вам это нужно, но вы можете использовать Hash#delete_if
RSpec.describe do
let(:hash1) { {'name' => 'XXXXX', 'age' => 29, 'DOB' => 'dd/mm/yyyy'} }
let(:hash2) { {'name' => 'XXXXX', 'age' => 29, 'DOB' => 'dd/mm/yyyy'} }
it 'should correctly compare two subhashes' do
expect(hash1.delete_if { |k,_| k == 'DOB' }).to eql(hash2.delete_if { |k,_| k == 'DOB' })
end
end
Если вы хотите сделать свой expect
более аккуратным, вы можете преобразовать хэши раньше.
Также вы можете использовать Hash#reject
RSpec.describe do
it 'should correctly compare two subhashes' do
hash1 = {'name' => 'XXXXX', 'age' => 29, 'DOB' => 'dd/mm/yyyy'}
hash2 = {'name' => 'XXXXX', 'age' => 29, 'DOB' => 'dd/mm/yyyy'}
hash1, hash2 = [hash1, hash2].map { |h| h.reject { |k,_| k == 'DOB' } }
expect(hash1).to eql(hash2)
end
end
Комментарии:
1. Я думаю, вы ошибочно приняли ‘DOB’ за ‘name’.
2. @sawa, спасибо. Я заметил, что имена разные (
"XXXXX"
и"XXXXx"
) и ввел себя в заблуждение..3. Не было бы удобно иметь метод хэша
delete2
, такой{ a:1, b:2, c:3, d:4 }.delete2(:b, :d) #=> { a:1, c:3 }
, чтобы без изменения получателя?4. @CarySwoveland Хорошая идея. Выглядит красиво. Возможно, когда-нибудь появятся в Ruby.
Ответ №2:
Вместо сравнения двух временных хэшей, которые равны H1
и H2
с удаленным ключом 'DOB'
(если присутствует), можно сравнить два временных хэша, которые имеют ключи 'DOB'
с одинаковым значением. Это значение произвольно; я использовал nil
.
expect(H1.merge('DOB'=>nil).to eq(H2.merge('DOB'=>nil)))
Другой способ:
expect((H1.keys|H2.keys).all? do |k|
k=='DOB' || (H1.key?(k) amp;amp; H2.key?(k) amp;amp; H1[k]==H2[k])
end.to eq(true)
H1.key?(k) amp;amp; H2.key?(k)
существует ли на случай, если один из хэшей имеет ключ k
со значением nil
, а другой хэш не имеет ключа k
.
Это имеет преимущество в том, что у него более скромные требования к памяти, чем у двух подходов, о которых я упоминал выше.
Комментарии:
1. Асимметрия уменьшает красоту. Я думаю, вы можете просто объединить
{'DOB' => nil}
оба хэша.2. @sawa, согласен. Я внес изменения. Спасибо.
3. Вы должны переключить приемник и аргумент для слияния относительно H1. В противном случае, если у H1 было значение для DOB, отличное от nil, …
4. Будем надеяться, что я, наконец, понял это правильно. 🙂 (Обратите внимание, что у моих смайликов есть носы.)