Ruby on rails 对这些类型的字符串进行排序的最佳方法是什么?
我需要获取目录和子目录中的所有文件,每个文件都有日期附加到文件名,如product\u log\u 2016-11-17.txt 用于获取我使用的目录中的文件列表Ruby on rails 对这些类型的字符串进行排序的最佳方法是什么?,ruby-on-rails,arrays,ruby,sorting,Ruby On Rails,Arrays,Ruby,Sorting,我需要获取目录和子目录中的所有文件,每个文件都有日期附加到文件名,如product\u log\u 2016-11-17.txt 用于获取我使用的目录中的文件列表 all_logs = Dir["#{Rails.root}/log/product_logs/**/*.txt"] 它返回完整路径文件,如下所示(我已从每个条目中删除了我的系统路径: [ "/log/product_logs/new_2/product_log_2016-11-17.txt", "/log/product_l
all_logs = Dir["#{Rails.root}/log/product_logs/**/*.txt"]
它返回完整路径文件,如下所示(我已从每个条目中删除了我的系统路径:
[
"/log/product_logs/new_2/product_log_2016-11-17.txt",
"/log/product_logs/new_2/products_log_2016-11-03.txt",
"/log/product_logs/new_1/products_log_2016-10-04.txt",
"/log/product_logs/new_1/product_log_2016-11-17.txt",
"/log/product_logs/new_1/products_log_2016-11-03.txt"
]
但我想按日期对列表进行排序,如下所示:
[
"/log/product_logs/new_2/product_log_2016-11-17.txt",
"/log/product_logs/new_1/product_log_2016-11-17.txt",
"/log/product_logs/new_2/products_log_2016-11-03.txt",
"/log/product_logs/new_1/products_log_2016-11-03.txt",
"/log/product_logs/new_1/products_log_2016-10-04.txt"
]
我试过这样做:
all_logs.sort{|a, b|b.split("/").last.split("_").last.split(".").first <=>a.split("/").last.split("_").last.split(".").first }
all|u log.sort{a,b|b.split(“/”).last.split(“.”)。last.split(“.”)。first a.split(“/”).last.split(“.”。first}
这是可行的,但似乎不是一个好的解决方案,有人能告诉我什么是最好的方法来停止这种类型的列表吗?您可以尝试以下方法:
all_logs = [
"/log/product_logs/new_2/product_log_2016-11-17.txt",
"/log/product_logs/new_2/products_log_2016-11-03.txt",
"/log/product_logs/new_1/products_log_2016-10-04.txt",
"/log/product_logs/new_1/product_log_2016-11-17.txt",
"/log/product_logs/new_1/products_log_2016-11-03.txt"
]
all_logs.sort { |a, b| b.split("/").last.to_date <=> a.split("/").last.to_date }
所有_日志=[
“/log/product_logs/new_2/product_log_2016-11-17.txt”,
“/log/product_logs/new_2/products_log_2016-11-03.txt”,
“/log/product_logs/new_1/products_log_2016-10-04.txt”,
“/log/product_logs/new_1/product_log_2016-11-17.txt”,
“/log/product_logs/new_1/products_log_2016-11-03.txt”
]
所有日志.sort{a,b | b.split(“/”).last.to_date a.split(“/”).last.to_date}
您可以执行以下操作:
# Returns:
#
# [
# ["/log/product_logs/new_2/product_log_2016-11-17.txt", "2016-11-17"],
# ...
# ]
date_mapping = array.map { |s| [s, s.match(/\d{4}-\d{2}-\d{2}/)[0]] }
# Sort arrays, and then get the first elements.
date_mapping.sort { |a, b| [b[1], a[0]] <=> [a[1], b[0]] }.map(&:first)
#返回:
#
# [
#[“/log/product_logs/new_2/product_log_2016-11-17.txt”,“2016-11-17”],
# ...
# ]
date|u mapping=array.map{s |[s,s.match(/\d{4}-\d{2}-\d{2}/)[0]}
#对数组进行排序,然后获取第一个元素。
date|mapping.sort{| a,b |[b[1],a[0]][a[1],b[0]]}.map(&:first)
请注意以下两行之间的差异:
date_mapping.sort { |a, b| [b[1], a[0]] <=> [a[1], b[0]] }
date_mapping.sort { |a, b| [b[1], b[0]] <=> [a[1], a[0]] }
date_mapping.sort{| a,b |[b[1],a[0][a[1],b[0]]
date|mapping.sort{| a,b |[b[1],b[0]][a[1],a[0]}
数组的第二个元素指定如何处理使用相同日期的字符串
▶ input.sort_by { |i| [i[/\d{4}-\d{1,2}-\d{1,2}/], i[/\d+/]] }
#⇒ [
# [0] "/log/product_logs/new_1/products_log_2016-10-04.txt",
# [1] "/log/product_logs/new_1/products_log_2016-11-03.txt",
# [2] "/log/product_logs/new_2/products_log_2016-11-03.txt",
# [3] "/log/product_logs/new_1/product_log_2016-11-17.txt",
# [4] "/log/product_logs/new_2/product_log_2016-11-17.txt"
# ]
与给出的答案相比,有两个优点:
- 它按
编号对同一日期进行排序,然后new\
比sort\u by
快得多sort
要接收降序排序,只需在最后调用
Enumerable#reverse
。有任何方法可以立即对文件列表进行排序,我的意思是不需要在获取列表后进行排序?@Thorin我认为您必须在获取名称后显式进行排序。这似乎是一个更好的解决方案,但我只需要按日期排序,还需要n如果只需要获取那些与模式匹配的文件,我可以直接获取这些文件吗?比如File.open(File_path,“rb”).grep(/“id”=>123/)请参见Dir.glob
:您可以使用这样的模式(而不是regex):Dir.glob('*[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9]*)
一个更好的解决方案+1,可能只需要一个反向
。@dp7是的,感谢关于反向
的提示,更新。当日期如下:2016-8时,它将失败-03@Thorin如果月份和日期可能是1位数,请使用\d{1,2}
匹配器,我已经更新了答案。