2013-06-27 75 views
34

這是一個常見的,重複的習慣用法:使用正則表達式過濾數組,然後返回一個子數組。我的方法看起來不像Ruby(我來自Java)。我最終有許多方法看起來很像這樣。Ruby:通過正則表達式過濾數組?

什麼是改進此代碼的慣用Ruby方法?

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

你是如何得到的文件名?如果從磁盤中,你可以使用'Dir.glob('*。jpe?g')' –

+0

檢索名稱時對它們進行過濾。我認爲幾乎所有人都誤解了我的問題(可能是因爲我問了很多問題)。該示例可能會過載。這不是關於圖像或文件名或文件擴展名。這是關於過濾數組,以及更好的方法來做到這一點。 – allanberry

回答

55

如果你想找到所有的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"]] 
15
$ 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」不管情況。

+1

「select」方法就是我在這裏尋找的(或者說「拒絕」方法,現在我已經找到了它)。謝謝。 – allanberry

18

看看Enumerable.grep,它是一個非常強大的查找/過濾t在任何可枚舉的東西中彈奏。

+0

這就像狄更斯。我可能會從現在開始使用它,但從狹義上講,「選擇」方法就是我在這個問題中所討論的。非常感謝。 – allanberry

+0

是的,'grep'非常棒,部分原因是它使用'==='來比較接收者的元素和'grep'的參數。這允許你編寫例如'[「abc」,「bcd」,「cbd」]。grep(/ .b。/)#=> [「abc」,「cbd」]'和'[{a :1},4,{b:2},「hat」]。grep(Hash)#=> [{:a => 1},{:b => 2}]'。 –

3

對於這個特定問題,我們可以不用正則表達式。使用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"] 
9
images = %w[foo.gif foo.png foo.jpg bar.jpeg moo.JPG] 
images.grep(/.jpg/g) # => ["foo.jpg", "moo.JPG"] 
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" 
] 

/gucio