如何基于扩展名数组筛选Ruby中的文件名数组?
更优雅的Ruby文件名筛选实现
首先要纠正你现有select写法的问题:exts.each { ... }的返回值始终是exts数组本身,所以这个条件永远为真,会把所有文件都选出来,达不到筛选目的。
下面推荐几种更简洁优雅的实现方式:
方式一:用any?实现精准匹配
any?会在数组中存在任意元素满足条件时返回true,搭配end_with?比include?更严谨(避免文件名中间包含扩展名的误匹配,比如file.zip.txt不会被选中):
exts = ['.zip', '.tgz', '.sql'] files = ['file1.txt', 'file2.doc', 'file2.tgz', 'file3.sql', 'file6.foo', 'file4.zip'] filtered_files = files.select { |file| exts.any? { |ext| file.end_with?(ext) } } # 输出结果: ["file2.tgz", "file3.sql", "file4.zip"]
方式二:正则表达式批量匹配
把扩展名数组转为正则表达式,一次性完成匹配,适合扩展名数量较多的场景:
ext_regex = /\.(zip|tgz|sql)$/ # 末尾$确保匹配文件结尾的扩展名 filtered_files = files.select { |file| file.match?(ext_regex) }
如果需要忽略大小写,可在正则后加i修饰符:/\.(zip|tgz|sql)$/i
方式三:利用标准库提取扩展名+集合查找
用Ruby标准库的File.extname精准提取扩展名,再配合集合(查找效率比数组更高)判断是否在目标列表中:
ext_set = exts.to_set filtered_files = files.select do |file| ext_set.include?(File.extname(file)) end
补充说明
你给出的预期结果里包含"file1.zip",但原files数组中并没有该文件,属于笔误,实际正确筛选结果应为["file2.tgz", "file3.sql", "file4.zip"]。
内容的提问来源于stack exchange,提问作者Steve K
相关产品推荐
相关产品推荐

