[英]simple hash merge by array of keys and values in ruby (with perl example)
In Perl to perform a hash update based on arrays of keys and values I can do something like:在 Perl 执行基于 arrays 的键和值的 hash 更新我可以执行以下操作:
@hash{'key1','key2','key3'} = ('val1','val2','val3');
In Ruby I could do something similar in a more complicated way:在 Ruby 中,我可以用更复杂的方式做类似的事情:
hash.merge!(Hash[ *[['key1','key2','key3'],['val1','val2','val3']].transpose ])
OK but I doubt the effectivity of such procedure.好的,但我怀疑这种程序的有效性。
Now I would like to do a more complex assignment in a single line.现在我想在一行中做一个更复杂的分配。
Perl example: Perl 示例:
(@hash{'key1','key2','key3'}, $key4) = &some_function();
I have no idea if such a thing is possible in some simple Ruby way.我不知道这样的事情是否可以通过一些简单的 Ruby 方式实现。 Any hints?
有什么提示吗?
For the Perl impaired, @hash{'key1','key2','key3'} = ('a', 'b', 'c')
is a hash slice and is a shorthand for something like this:对于 Perl 受损,
@hash{'key1','key2','key3'} = ('a', 'b', 'c')
是hash 切片,是这样的简写:
$hash{'key1'} = 'a';
$hash{'key2'} = 'b';
$hash{'key3'} = 'c';
In Ruby 1.9 Hash.[]
can take as its argument an array of two-valued arrays (in addition to the old behavior of a flat list of alternative key/value arguments).在 Ruby 1.9
Hash.[]
中,可以将二值 arrays 数组作为其参数(除了替代键/值的平面列表的旧行为)。 So it's relatively simple to do:所以做起来比较简单:
mash.merge!( Hash[ keys.zip(values) ] )
I do not know perl, so I'm not sure what your final "more complex assignment" is trying to do.我不知道 perl,所以我不确定您最终的“更复杂的任务”要做什么。 Can you explain in words—or with the sample input and output—what you are trying to achieve?
你能用文字或示例输入和输出来解释你想要实现的目标吗?
Edit : based on the discussion in @fl00r's answer, you can do this:编辑:根据@fl00r's answer中的讨论,您可以这样做:
def f(n)
# return n arguments
(1..n).to_a
end
h = {}
keys = [:a,:b,:c]
*vals, last = f(4)
h.merge!( Hash[ keys.zip(vals) ] )
p vals, last, h
#=> [1, 2, 3]
#=> 4
#=> {:a=>1, :b=>2, :c=>3}
The code *a, b = some_array
will assign the last element to b
and create a
as an array of the other values.代码
*a, b = some_array
会将最后一个元素分配给b
并创建a
作为其他值的数组。 This syntax requires Ruby 1.9.此语法需要 Ruby 1.9。 If you require 1.8 compatibility, you can do:
如果您需要 1.8 兼容性,您可以执行以下操作:
vals = f(4)
last = vals.pop
h.merge!( Hash[ *keys.zip(vals).flatten ] )
You could redefine []=
to support this:您可以重新定义
[]=
来支持这一点:
class Hash
def []=(*args)
*keys, vals = args # if this doesn't work in your version of ruby, use "keys, vals = args[0...-1], args.last"
merge! Hash[keys.zip(vals.respond_to?(:each) ? vals : [vals])]
end
end
Now use现在使用
myhash[:key1, :key2, :key3] = :val1, :val2, :val3
# or
myhash[:key1, :key2, :key3] = some_method_returning_three_values
# or even
*myhash[:key1, :key2, :key3], local_var = some_method_returning_four_values
you can do this你可以这样做
def some_method
# some code that return this:
[{:key1 => 1, :key2 => 2, :key3 => 3}, 145]
end
hash, key = some_method
puts hash
#=> {:key1 => 1, :key2 => 2, :key3 => 3}
puts key
#=> 145
UPD UPD
In Ruby you can do "parallel assignment", but you can't use hashes like you do in Perl ( hash{:a, :b, :c)
).在 Ruby 中,您可以执行“并行分配”,但不能像在 Perl 中那样使用散列(
hash{:a, :b, :c)
)。 But you can try this:但是你可以试试这个:
hash[:key1], hash[:key2], hash[:key3], key4 = some_method
where some_method
returns an Array with 4 elements.其中
some_method
返回一个包含 4 个元素的数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.