我有一个扩展名数组和一个文件名数组:
exts = ['.zip', '.tgz', '.sql']
files = ['file1.txt', 'file2.doc', 'file2.tgz', 'file3.sql', 'file6.foo', 'file4.zip']
我想按一个或多个匹配的扩展名筛选文件名。在这种情况下,结果将是:
["file1.zip", "file2.tgz", "file3.sql", "file4.zip"]
我知道我可以用一个嵌套循环来实现这一点:
exts.each_with_object([]) do |ext, arr|
files.each do |file|
arr << entry if file.include?(ext)
end
end
这让我感觉很糟糕。使用select,我可以避免嵌套循环的感觉:
files.select { |file| exts.each { |ext| file.include?(ext) } }
这很有效,感觉也更好。我还缺少一种更优雅的方式吗?
3条答案
按热度按时间nszi6y051#
我将使用
Enumerable#grep
和如下正则表达式:我使用
Regexp.union
而不是简单的exts.join('|')
,因为exts
包含在正则表达式中具有特殊含义的点(.
)。Regexp.union
会自动转义这些点。gwo2fgha2#
再进一步考虑一下,我意识到如果稍微改变一下逻辑,我可以使
select
变得更好:据我所知,这是我能弄到的最干净的了。
ttvkxqim3#
如果你把扩展存储在一个集合中,你会把运行时复杂度从O(NM)降低到O(N)。