【问题标题】:Ruby: the closest date to specific dateRuby:最接近特定日期的日期
【发布时间】:2021-01-01 11:09:59
【问题描述】:

我的 ruby​​ 脚本有问题。我有一个数组

files = ["2020-09-14.access","2020-09-13.access","2020-09-11.access","2020-09-10.access","2020-09-09.access","2020-09-08.access","2020-09-07.access","2020-09-05.access","2020-09-04.access","2020-09-02.access","2020-09-01.access","2020-09-14.sale","2020-09-12.sale","2020-09-08.sale","2020-09-07.sale","2020-09-06.sale","2020-09-04.sale",]

包含作为文件名的值。有两种类型的文件:访问和销售。每个文件名都包含文件创建日期。从每种文件类型中,我只想获取这些值,这些值具有两天前创建的较早日期开始的表单文件。对于文件类型销售没有问题,今天是2020-09-14,前两天创建的文件是2020-09-12.sale。但是如果访问文件没有创建文件2020-09-12,所以我想要日期最接近2020-09-12的文件,这意味着值2020-09-10.access,我在这里堆叠。总之我想得到这样的数组

to_del_files = [["2020-09-10.access","2020-09-09.access","2020-09-08.access","2020-09-07.access","2020-09-05.access","2020-09-04.access","2020-09-02.access","2020-09-01.access"],["2020-09-12.sale","2020-09-08.sale","2020-09-07.sale","2020-09-06.sale","2020-09-04.sale"]]

我的代码如下:

require 'date'
files = ["2020-09-14.access","2020-09-13.access","2020-09-10.access","2020-09-09.access","2020-09-08.access","2020-09-07.access","2020-09-05.access","2020-09-04.access","2020-09-02.access","2020-09-01.access","2020-09-14.sale","2020-09-12.sale","2020-09-08.sale","2020-09-07.sale","2020-09-06.sale","2020-09-04.sale",]

names = files.map {|x| x.split('.')[1] }.uniq
puts names
date = Date.today
date2ago = date -2
to_del_files = []
names.each do |item|
    tmp = files.select { |x| x =~ /#{item}/ }
    flag = tmp.select {|x| x =~ /#{date2ago}/ }
    if flag.size > 0
        index = tmp.find_index("#{flag[0]}")
        to_del_files << tmp[index..-1]
    else
        #what to do in case where there is no such date in files
    end
end
puts to_del_files

感谢您的帮助。

【问题讨论】:

  • 如果没有 Rails 标签,则假设您想要一个纯 Ruby 解决方案。

标签: arrays ruby date


【解决方案1】:

为了让你得到要删除的文件:

def old_files(files, date)
  files.sort.filter { |file| Date.parse(file) < date }
end

然后你可以使用:

files = ["2020-09-14.access","2020-09-13.access","2020-09-10.access","2020-09-09.access","2020-09-08.access","2020-09-07.access","2020-09-05.access","2020-09-04.access","2020-09-02.access","2020-09-01.access","2020-09-14.sale","2020-09-12.sale","2020-09-08.sale","2020-09-07.sale","2020-09-06.sale","2020-09-04.sale",]

today = Date.today
date = today -2

to_del_files = old_files(files, date)

【讨论】:

  • 这需要 Rails 或至少 ActiveSupport 才能工作
  • 我稍微修改了这段代码 def old_files(files, date) files.sort { |a, b| a b }.filter { |文件| Date.parse(file)
  • 我建议你使用Date::strptime而不是Date.parse,因为后者可能会返回意想不到的结果。例如,Date.parse("But maybe Bob was the murderer after all") #=&gt; #&lt;Date: 2020-05-01 ((2458971j,0s,0n),+0s,2299161j)&gt;
【解决方案2】:

我了解到您希望从files 中选择与等于或早于给定日期的日期相对应的元素。如果正确,您可以按照以下方式进行操作。

files = [
  "2020-09-14.access", "2020-09-13.access", "2020-09-11.access",
  "2020-09-10.access", "2020-09-09.access", "2020-09-08.access",
  "2020-09-07.access", "2020-09-05.access", "2020-09-04.access",
  "2020-09-02.access", "2020-09-01.access", "2020-09-14.sale",
  "2020-09-12.sale",   "2020-09-08.sale",   "2020-09-07.sale",
  "2020-09-06.sale",   "2020-09-04.sale"
]
require 'date'

def files_on_or_before_date(arr)
  files_on_or_before_target_date(arr, Date.now-2)
end

def files_on_or_before_target_date(arr, target_date)
  arr.select { |d| Date.strptime(d, '%Y-%m-%d') <= target_date }
end
files_on_or_before_target_date(files, Date.new(2020, 9, 12))
  #=> ["2020-09-11.access", "2020-09-10.access", "2020-09-09.access",
  #    "2020-09-08.access", "2020-09-07.access", "2020-09-05.access",
  #    "2020-09-04.access", "2020-09-02.access", "2020-09-01.access",
  #    "2020-09-12.sale",   "2020-09-08.sale",   "2020-09-07.sale",
  #    "2020-09-06.sale",   "2020-09-04.sale"] 
files_on_or_before_target_date(files, Date.new(2020, 9, 10))
  #=> ["2020-09-10.access", "2020-09-09.access", "2020-09-08.access",
  #    "2020-09-07.access", "2020-09-05.access", "2020-09-04.access",
  #    "2020-09-02.access", "2020-09-01.access", "2020-09-08.sale",
  #    "2020-09-07.sale",   "2020-09-06.sale",   "2020-09-04.sale"]

这些返回值当然可以添加到数组中。

请参阅Date::strptimeDateTime#strftime,后者了解日期格式指令。

Date.strptime("2020-09-14.access", '%Y-%m-%d')

返回相同的 Date 对象

Date.strptime("2020-09-14", '%Y-%m-%d')

为了防止将来Date::strptime的实现可能发生变化,d的参数d可以替换为d[/[^.]+/]d[0, d.index('.')],当d = "2020-09-14.access"时两者都变为"2020-09-14"

【讨论】:

  • 感谢您的回答,但实际上我想选择 2 天前或更早创建的文件。如果数组不包含今天创建的任何类型的文件,我想早点选择第一个。在上面的例子中,没有 2020-09-12.access 文件,但更早的文件是 2020-09-10.access 并且这个文件和任何更旧的文件我都不想推送到新数组。
  • 你说,“如果数组不包含今天创建的任何类型的文件,我想早点选择第一个”。那是一个文件。后来你说,“......这个文件和任何旧的我想推到新的阵列。”。我以为你想要后者。请解释我的方法在我考虑的两个日期应该返回什么。
猜你喜欢
  • 2018-06-04
  • 2022-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
相关资源
最近更新 更多