ruby 根据其他数组中的值筛选拼音数组

xxhby3vn  于 2022-11-22  发布在  Ruby
关注(0)|答案(3)|浏览(175)

我有一个扩展名数组和一个文件名数组:

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) } }

这很有效,感觉也更好。我还缺少一种更优雅的方式吗?

nszi6y05

nszi6y051#

我将使用Enumerable#grep和如下正则表达式:

exts = ['.zip', '.tgz', '.sql']
files = ['file1.txt', 'file2.doc', 'file2.tgz', 'file3.sql', 'file6.foo', 'file4.zip']

files.grep(/#{Regexp.union(exts)}$/)
#=> ["file2.tgz", "file3.sql", "file4.zip"]

我使用Regexp.union而不是简单的exts.join('|'),因为exts包含在正则表达式中具有特殊含义的点(.)。Regexp.union会自动转义这些点。

gwo2fgha

gwo2fgha2#

再进一步考虑一下,我意识到如果稍微改变一下逻辑,我可以使select变得更好:

exts = ['zip', 'tgz', 'sql']
files.select{ |file| exts.include?(file) }

据我所知,这是我能弄到的最干净的了。

ttvkxqim

ttvkxqim3#

如果你把扩展存储在一个集合中,你会把运行时复杂度从O(NM)降低到O(N)。

exts = ['.zip', '.tgz', '.sql'].to_set
files.select { |file| exts.include?(File.extname(file)) }

相关问题