我有一个这样的散列:

params = { :irrelevant => "A String",
           :choice1 => "Oh look, another one",
           :choice2 => "Even more strings",
           :choice3 => "But wait",
           :irrelevant2 => "The last string" }

我想要一个简单的方法来拒绝所有不是choice+int的键。可以是choice1,或者从choice1到choice10。它变化。

我如何用单词选择和后面的一个或多个数字来挑选键?

奖金:

将散列转换为以tab (\t)作为分隔符的字符串。我这样做了,但它花了几行代码。通常大师级的卢比手可以在一行或几行内完成。


当前回答

使用散列切片

{ a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
# => {:a=>1, :b=>2}

# If you have an array of keys you want to limit to, you should splat them:
valid_keys = [:mass, :velocity, :time]
search(options.slice(*valid_keys))

其他回答

params = { :irrelevant => "A String",
           :choice1 => "Oh look, another one",
           :choice2 => "Even more strings",
           :choice3 => "But wait",
           :irrelevant2 => "The last string" }

choices = params.select { |key, value| key.to_s[/^choice\d+/] }
#=> {:choice1=>"Oh look, another one", :choice2=>"Even more strings", :choice3=>"But wait"}

关于奖金问题:

If you have output from #select method like this (list of 2-element arrays): [[:choice1, "Oh look, another one"], [:choice2, "Even more strings"], [:choice3, "But wait"]] then simply take this result and execute: filtered_params.join("\t") # or if you want only values instead of pairs key-value filtered_params.map(&:last).join("\t") If you have output from #delete_if method like this (hash): {:choice1=>"Oh look, another one", :choice2=>"Even more strings", :choice3=>"But wait"} then: filtered_params.to_a.join("\t") # or filtered_params.values.join("\t")

我有一个类似的问题,在我的情况下,解决方案是一行,即使键不是符号也能工作,但你需要在数组中有标准键

criteria_array = [:choice1, :choice2]

params.select { |k,v| criteria_array.include?(k) } #=> { :choice1 => "Oh look another one",
                                                         :choice2 => "Even more strings" }

另一个例子

criteria_array = [1, 2, 3]

params = { 1 => "A String",
           17 => "Oh look, another one",
           25 => "Even more strings",
           49 => "But wait",
           105 => "The last string" }

params.select { |k,v| criteria_array.include?(k) } #=> { 1 => "A String"}

在Ruby中,hash# select是一个正确的选项。如果你使用Rails,你可以使用Hash#slice和Hash#slice!例:(rails 3.2.13)

h1 = {:a => 1, :b => 2, :c => 3, :d => 4}

h1.slice(:a, :b)         # return {:a=>1, :b=>2}, but h1 is not changed

h2 = h1.slice!(:a, :b)   # h1 = {:a=>1, :b=>2}, h2 = {:c => 3, :d => 4}

使用散列切片

{ a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
# => {:a=>1, :b=>2}

# If you have an array of keys you want to limit to, you should splat them:
valid_keys = [:mass, :velocity, :time]
search(options.slice(*valid_keys))