【问题标题】:Ruby: filter array by regex?Ruby:通过正则表达式过滤数组?
【发布时间】:2013-06-25 15:30:14
【问题描述】:

这对我来说是一个常见的、重复的习惯用法:使用正则表达式过滤一个数组,然后返回一个子数组。我的方法看起来不太像 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

【问题讨论】:

  • 你是如何获得文件名的?如果从磁盘中,您可以在检索名称时使用 Dir.glob('*.jpe?g') 过滤它们
  • 我想几乎每个人都误解了我的问题(也许是因为我问得不好)。该示例可能加载过多。这与图像或文件名或文件扩展名无关。这是关于数组的过滤,以及一个更好的方法来做到这一点。

标签: ruby regex arrays filter


【解决方案1】:
$ 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”,而不管大小写。

【讨论】:

  • “选择”方法是我在这里寻找的(或者更确切地说是“拒绝”方法,现在我已经找到了)。谢谢。
【解决方案2】:

如果你想找到所有的 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"]]

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 这就像狄更斯一样工作。从现在开始我可能会使用它,但从狭义上讲,“选择”方法是我在这个问题中所追求的。非常感谢。
    • 是的,grep 很棒,部分原因是它使用=== 将接收者的元素与grep 的参数进行比较。这允许您编写,例如,["abc", "bcd", "cbd"].grep(/.b./) #=&gt; ["abc", "cbd"] [{a:1}, 4, {b:2}, "hat"].grep(Hash) #=&gt; [{:a=&gt;1}, {:b=&gt;2}]
    【解决方案4】:

    对于这个特定问题,我们可以不使用 regex。使用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"]
    

    【讨论】:

      【解决方案5】:
      images = %w[foo.gif foo.png foo.jpg bar.jpeg moo.JPG]
      images.grep(/.jpg/i) # => ["foo.jpg", "moo.JPG"]
      

      【讨论】:

        【解决方案6】:
        ta, tb = files.partition{|f| f[/(.*\.jpe*g)/]}
        
        ap ta
        [
            [0] "bar.jpg",
            [1] "foo.jpeg"
        ]
        
        
        ap tb
        [
            [0] "foo.gif",
            [1] "bar.gif"
        ]
        

        /gucio

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多