1

在一个方法中,我得到一个传入的选项列表。有些与特定范围有关。我想将这些特殊键存储在另一个散列中,以便能够将其传递给不同的方法,并将它们从原始散列中删除。

(我实际上是在写一个 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 }

现在我的问题是有更好的,即更聪明的方法吗?

也许只是糖,但我想知道。

4

4 回答 4

1

也许是提取物!active_support 中的方法可以工作吗?

于 2013-06-22T11:54:30.793 回答
1

我只知道鲁比。所以这里是我的 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}
于 2013-06-22T12:31:04.067 回答
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}

这里有一种方法可以改进刘巨的回答:

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但是,如果哈希中的任何键的实际值为nilor false(不知道是否需要保留它们),您将失去选择:

all_options = { :key1 => 1, :key2 => nil, :something_else => 42 }

这是一种保持false's 的方法

my_options = all_options.extract!(*my_keys).keep_if {|k,v| !v.nil?}

nilps如果您从以下位置存储密钥,则可以保留包括 s 在内的所有值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}
于 2013-06-22T13:58:40.660 回答
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
于 2018-12-18T08:49:35.283 回答