在Ruby中获取以url结尾的所有键的最佳/最干净的方法
我有一个如下所示的散列:在Ruby中获取以url结尾的所有键的最佳/最干净的方法,ruby,Ruby,我有一个如下所示的散列: { "id" => 108, "position" => 0, "attachment_content_type" => "image/jpeg", "attachment_updated_at" => "2014-11-14T21:50:46.395Z", "attachment_width" => 1140,
{
"id" => 108,
"position" => 0,
"attachment_content_type" => "image/jpeg",
"attachment_updated_at" => "2014-11-14T21:50:46.395Z",
"attachment_width" => 1140,
"attachment_height" => 1140,
"alt" => "",
"viewable_type" => "Spree::Variant",
"viewable_id" => 43,
"mini_url" => "xyz,
"small_url" => "http:blahblahblah",
"product_url" => "http:blahblahblah",
"large_url" => "http:blahblahblah",
"xlarge_url" => "http:blahblahblah"
}
{
urls: {
mini_url: "blaaaah",
(etc.)
}
}
如何使用splat*获取以url结尾的所有键?有办法吗
此散列位于Rails的序列化程序中,我尝试将URL嵌套在JSON结构中,如下所示:
{
"id" => 108,
"position" => 0,
"attachment_content_type" => "image/jpeg",
"attachment_updated_at" => "2014-11-14T21:50:46.395Z",
"attachment_width" => 1140,
"attachment_height" => 1140,
"alt" => "",
"viewable_type" => "Spree::Variant",
"viewable_id" => 43,
"mini_url" => "xyz,
"small_url" => "http:blahblahblah",
"product_url" => "http:blahblahblah",
"large_url" => "http:blahblahblah",
"xlarge_url" => "http:blahblahblah"
}
{
urls: {
mini_url: "blaaaah",
(etc.)
}
}
想法?不确定在此处使用splat运算符的意思,但您可以通过以下代码轻松提取它们:
input = {
"id" => 108,
"position" => 0,
"attachment_content_type" => "image/jpeg",
"attachment_file_name" => "Strainer_-_Blue_Apron_Marketplace_213.jpg",
"type" => "Spree::Image",
"attachment_updated_at" => "2014-11-14T21:50:46.395Z",
"attachment_width" => 1140,
"attachment_height" => 1140,
"alt" => "",
"viewable_type" => "Spree::Variant",
"viewable_id" => 43,
"mini_url" => "https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/mini/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"small_url" => "https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/small/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"product_url" => "https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/product/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"large_url" => "https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/large/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"xlarge_url" => "https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/xlarge/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846"
}
urls = input.each_with_object({}) do |(key,value),acc|
if key.end_with?("_url")
acc[key] = value
end
end
puts urls.inspect
如何使用splat*获取以url结尾的所有键?有办法吗
Splats无法做到这一点
您可以使用Hashselect:
输出:
{"mini_url"=>
"https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/mini/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"small_url"=>
"https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/small/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"product_url"=>
"https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/product/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"large_url"=>
"https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/large/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846",
"xlarge_url"=>
"https://s3.amazonaws.com/marketplace-staging.blueapron.com/app/public/spree/products/108/xlarge/Strainer_-_Blue_Apron_Marketplace_213.jpg?1416001846"}
您想要散列还是值。如果我只想要这些值,我会首先利用键并选择: 它使用*,但没有理由使用它。根据经验和测试,我知道这会减慢检查速度并浪费CPU。简化模式会更快:
hash.keys.select{ |k| k[/_url$/] } # => ["mini_url", "small_url"]
更快的是:
hash.keys.select{ |k| k.end_with?('_url') } # => ["mini_url", "small_url"]
从那里,我将使用值_at获取相关值:
url_keys = hash.keys.select{ |k| k.end_with?('_url') } # => ["mini_url", "small_url"]
hash.values_at(*url_keys) # => ["mini_url_value", "small_url_value"]
构建一个新的散列很容易:
url_keys = hash.keys.select{ |k| k.end_with?('_url') } # => ["mini_url", "small_url"]
url_keys.zip(hash.values_at(*url_keys)).to_h # => {"mini_url"=>"mini_url_value", "small_url"=>"small_url_value"}
hash.select{ |k| k.end_with?('_url') } # => {"mini_url"=>"mini_url_value", "small_url"=>"small_url_value"}
还可以将select与哈希一起使用,并将生成的数组数组转换回新的哈希:
url_keys = hash.keys.select{ |k| k.end_with?('_url') } # => ["mini_url", "small_url"]
url_keys.zip(hash.values_at(*url_keys)).to_h # => {"mini_url"=>"mini_url_value", "small_url"=>"small_url_value"}
hash.select{ |k| k.end_with?('_url') } # => {"mini_url"=>"mini_url_value", "small_url"=>"small_url_value"}
我用第一种方法摆脱习惯;这是Perl风格的方式,我写了很多Perl,它与旧Rubies兼容。Hash.select很长一段时间都没有返回哈希值,to_h作为数组的一部分不再可用。aaah+1表示end_with?我的第一反应是输入。键。选择。。。将更直接,但这会创建不需要的临时数组input.keys。所以,祝你好运。我唯一的建议是风格:acc[key]=value if key.end\u with?\u url。你也可以说,如果输入是你的散列,…,而不是重复答案中的散列。*是splat,但我不知道如何从散列中筛选条目。OP只需要密钥。请注意,您使用的是,而不是,因此.to_h是多余的。@CarySwoveland感谢.to_h提示。固定的OP在哪里说他们只需要钥匙?从预期的产量?似乎OP确实需要一个以_url结尾的键的散列。我认为你在回答中包含的标题和行都表明只需要这些键,但这并不重要,因为你可以始终附加。键。我有点困惑,您是否尝试显式使用glob样式语法来过滤哈希键,而不是使用end_with??如果是这样的话,您可以尝试使用正则表达式匹配器:key=~/^.*\u url$/Ah这很有效!这是一个glob而不是splat,对吧?不,这是一个正则表达式。如果你的实际问题是在标题中给出的,返回一个特定键的数组,你不应该用splat操作符的任何特定方法来陈述这个问题。当你给出一个例子时,请尽量使它小一些,这样它仍然能说明问题,五个键就足够了,并为每个输入对象分配一个变量,例如,h={id=>…},这样读者就可以在答案和注释中引用变量,而不必定义它。比如,看看毛里西奥的答案如何简化。