Несколько возвращаемых значений с массивами и хешами
Я считаю, что массивы в основном используются для возврата нескольких значений из методов:
def some_method
return [1, 2]
end
[a, b] = some_method # should yield a = 1 and b = 2
Я предполагаю, что это своего рода синтаксический сахар, который предоставляет Ruby. Можем ли мы получить аналогичный результат с хешами, например
def some_method
return { "a" => 1, "b" => 2 }
end
{"c", "d"} = some_method() # "c" => 1, "d" => 2
Я ищу результат { "c" => 1, "d" => 2 }
что, очевидно, не происходит. Есть ли другой способ сделать это? Я знаю, что мы можем вернуть хеш из метода и сохранить его и использовать его так
def some_method
return {"a" => 1, "b" => 2}
end
hash = some_method()
Просто любопытно, есть ли другой способ, похожий на тот, что с массивами, но с использованием хешей....
Я думаю, что более простой способ поставить вопрос будет...
# If we have a hash
hash = {"a" => 1, "b" => 2}
# Is the following possible
hash = {2, 3} # directly assigning values to the hash.
OR
# another example
{"c", "d"} = {2, 3} # c and d would be treated as keys and {2, 3} as respective values.
2 ответа
То, что вы спрашиваете, синтаксически невозможно.
То, чего вы хотите достичь, возможно, но вам придется его кодировать. Один из возможных способов сделать это показан ниже
hash = {"a" => 1, "b" => 2}
# Assign new keys
new_keys = ["c", "d"]
p [new_keys, hash.values].transpose.to_h
#=> {"c"=>1, "d"=>2}
# Assign new values
new_values = [3, 4]
p [hash.keys, new_values].transpose.to_h
#=> {"a"=>3, "b"=>4}
Если вы действительно хотите более простой и понятный способ сделать это, вы можете сделать monkey-patch Hash
класс и определить новые методы для манипулирования значениями keys
а также values
массив. Пожалуйста, имейте в виду, что не стоит связываться с основными классами. В любом случае, возможная реализация показана ниже. Используйте на свой риск.
class Hash
def values= new_values
new_values.each_with_index do |v, i|
self[keys[i]] = v if i < self.size
end
end
def keys= new_keys
orig_keys = keys.dup
new_keys.each_with_index do |k, i|
if i < orig_keys.size
v = delete(orig_keys[i])
self[k] = v
rehash
end
end
end
end
hash = {"a" => 1, "b" => 2}
hash.values = [2,3]
p hash
#=> {"a"=>2, "b"=>3}
hash.keys = ["c", "d"]
p hash
#=> {"c"=>2, "d"=>3}
hash.keys, hash.values = ["x","y"], [9, 10]
p hash
#=> {"x"=>9, "y"=>10}
hash.keys, hash.values = ["x","y"], [9, 10]
p hash
#=> {"x"=>9, "y"=>10}
# *** results can be unpredictable at times ***
hash.keys, hash.values = ["a"], [20, 10]
p hash
#=> {"y"=>20, "a"=>10}
Прежде всего, у вас есть синтаксическая ошибка. Вместо этого:
[a, b] = [1, 2]
вы должны использовать:
a, b = [1, 2]
И если вы хотите использовать подобный синтаксис с хешами, вы можете сделать:
a, b = { "c" => 1, "d" => 2 }.values # a => 1, b => 2
На самом деле это то же самое, что и версия массива, потому что Hash#values
возвращает массив значений хеш-функции в том порядке, в котором они были вставлены в хеш-код (потому что хэши ruby имеют хорошую функцию сохранения их порядка)