39

这对我来说是一个常见的、重复的习惯用法:使用正则表达式过滤数组,然后返回一个子数组。我的方法看起来不太像 Ruby(我来自 Java)。我最终有很多方法看起来很像这样。

改进此代码的惯用 Ruby 方法是什么?

def get_all_gifs(items_)
  output = Array.new
  filter = /\.jpg$/
  items_.each do |item|
    next if item =~ filter
    output << item
  end
  output
end
4

6 回答 6

74

如果你想找到所有的 GIF:

def get_all_gifs(files)
  files.select{ |i| i[/\.gif$/] }
end

如果要查找所有 jpeg:

def get_all_jpgs(files)
  files.select{ |i| i[/\.jpe?g$/] }
end

运行它们:

files = %w[foo.gif bar.jpg foo.jpeg bar.gif]
get_all_gifs(files) # => ["foo.gif", "bar.gif"]
get_all_jpgs(files) # => ["bar.jpg", "foo.jpeg"]

可是等等!还有更多!

如果您想按类型将它们全部分组,然后根据扩展名进行提取怎么办?:

def get_all_images_by_type(files)
  files.group_by{ |f| File.extname(f) }
end

以下是文件的类型:

get_all_images_by_type(files).keys # => [".gif", ".jpg", ".jpeg"]

以下是获取特定类型的方法:

get_all_images_by_type(files) # => {".gif"=>["foo.gif", "bar.gif"], ".jpg"=>["bar.jpg"], ".jpeg"=>["foo.jpeg"]}
get_all_images_by_type(files)['.gif'] # => ["foo.gif", "bar.gif"]
get_all_images_by_type(files).values_at('.jpg', '.jpeg') # => [["bar.jpg"], ["foo.jpeg"]]
于 2013-06-27T23:47:32.943 回答
24

看看Enumerable.grep,它是在任何可枚举的东西中查找/过滤事物的一种非常强大的方法。

于 2013-06-27T23:58:05.183 回答
16
$ cat foo.rb
images = %w[foo.gif foo.png foo.jpg bar.jpeg moo.JPG]
jpgs = images.select{|e| e =~ /\.jpe?g$/i}
puts jpgs.inspect

$ ruby foo.rb
["foo.jpg", "bar.jpeg", "moo.JPG"]

对您的正则表达式的更改是为了让您可以匹配除“jpg”之外的“jpeg”,而不管大小写。

于 2013-06-27T23:27:22.073 回答
13
images = %w[foo.gif foo.png foo.jpg bar.jpeg moo.JPG]
images.grep(/.jpg/i) # => ["foo.jpg", "moo.JPG"]
于 2015-01-27T13:52:25.553 回答
5

对于这个特定问题,我们可以不用正则表达式。利用String#end_with?

images = %w[foo.gif foo.png foo.jpg bar.jpeg moo.JPG]
images.find_all{|e| e.end_with?(".jpg",".jpeg")}
# => ["foo.jpg", "bar.jpeg"]
于 2013-06-28T03:57:07.950 回答
0
ta, tb = files.partition{|f| f[/(.*\.jpe*g)/]}

ap ta
[
    [0] "bar.jpg",
    [1] "foo.jpeg"
]


ap tb
[
    [0] "foo.gif",
    [1] "bar.gif"
]

/古乔

于 2016-02-10T19:31:18.887 回答