在一个方法中,我得到一个传入的选项列表。一些与特定范围有关。 我想将这些特殊键存储在另一个哈希中,以便能够将它传递给另一个方法,并从原始哈希中删除它们。
(我实际上是在编写一个rails simple_form自定义输入,但这没关系)
我有以下代码:
all_options = { :key1 => 1, :key2 => 2, :something_else => 42 }
my_keys = [:key1, :key2, :key3, :key4]
my_options = all_options.select {|k,v| my_keys.include?(k)}
all_options.delete_if {|k,v| my_keys.include?(k)}
# expecting
my_options == { :key1 => 1, :key2 => 2 }
all_options == { :something_else => 42 }
现在我的问题是有更好的,更明智的做法吗?
也许这只是糖,但我想知道。
答案 0 :(得分:1)
也许active_support中的extract!方法可以正常工作?
答案 1 :(得分:1)
我只知道Ruby。所以这里我的Ruby方法:
all_options = { :key1 => 1, :key2 => 2, :something_else => 42 }
my_keys = [:key1, :key2, :key3, :key4]
#below statement is your my_options
Hash[my_keys.map{|i| [i,all_options.delete(i)] if all_options.has_key? i }.compact]
# => {:key1=>1, :key2=>2}
all_options
# => {:something_else=>42}
答案 2 :(得分:1)
all_options = { :key1 => 1, :key2 => 2, :something_else => 42 }
my_keys = [:key1, :key2, :key3, :key4]
my_options = my_keys.inject({}) {|h,k| h[k] = all_options.delete(k) if all_options.key?(k);h}
all_options
# => {:something_else=>42}
my_options
# => {:key1=>1, :key2=>2}
这是改善Ju Liu答案的一种方法:
all_options = { :key1 => 1, :key2 => 2, :something_else => 42 }
my_keys = [:key1, :key2, :key3, :key4]
my_options = all_options.extract!(*my_keys).keep_if {|k,v| v}
all_options
# => {:something_else=>42}
my_options
# => {:key1=>1, :key2=>2}
但是,如果all_options
哈希中的任何键的实际值为nil
或false
(不知道是否需要保留它们),您将失去选项:
all_options = { :key1 => 1, :key2 => nil, :something_else => 42 }
这是保留false
的
my_options = all_options.extract!(*my_keys).keep_if {|k,v| !v.nil?}
P.S。如果您存储来自nil
的密钥,则可以保留所有值,包括all_options
:
all_options = { :key1 => 1, :key2 => 2, :something_else => 42 }
all_keys = all_options.keys
my_keys = [:key1, :key2, :key3, :key4]
my_options = all_options.extract!(*my_keys).keep_if {|k,v| all_keys.include?(k)}
all_options
# => {:something_else=>42}
my_options
# => {:key1=>1, :key2=>2}
答案 3 :(得分:0)
all_options = { key1: 1, key2: 2, something_else: 42 }
my_keys = [:key1, :key2, :key3, :key4]
my_options = my_keys.each_with_object({}) do |key, hash|
hash[key] = all_options.delete(key) if all_options.key?(key)
end