Можно сортировать массивы, но это может быть дорогостоящей операцией, если массивы большие.Если n
равен размеру массива, временная сложность heapsort, например, равна O(n log(n))
.Быстрее заменить массивы счетными хэшами, конструкция которых имеет временную сложность O(n)
.
h1 = { 'k1' => [1, 2, 1, 3, 2, 1], 'k2' => 'c' }
h2 = { 'k1' => [3, 2, 1, 2, 1, 1], 'k2' => 'c' }
def same?(h1, h2)
return false unless h1.size == h2.size
h1.all? do |k,v|
if h2.key?(k)
vo = h2[k]
if v.is_a?(Array)
if vo.is_a?(Array)
convert(v) == convert(vo)
end
else
v == vo
end
end
end
end
def convert(arr)
arr.each_with_object(Hash.new(0)) { |e,g| g[e] += 1 }
end
same?(h1, h2)
#=> true
Здесь
convert([1, 2, 1, 3, 2, 1])
#=> {1=>3, 2=>2, 3=>1}
convert([3, 2, 1, 2, 1, 1])
#=> {3=>1, 2=>2, 1=>3}
и
{1=>3, 2=>2, 3=>1} == {3=>1, 2=>2, 1=>3}
#=> true
См. Hash :: new , в частности, в случае, когда метод принимает аргумент, равный значению по умолчанию .
Защитное предложение return false unless h1.size == h2.size
должно гарантировать, чтоh2
не имеет ключей, которых нет в h1
.Обратите внимание, что следующее возвращает ложное значение nil
:
if false
#...
end
#=> nil
В нескольких местах я написал это, а не более многословное, но эквивалентное выражение
if false
#...
else
nil
end