在Ruby中有没有更好的方法来完成这个过滤和排序?

6ioyuze2  于 11个月前  发布在  Ruby
关注(0)|答案(1)|浏览(88)

(a)下面是一些类似的线条

......, start Mon 10/30 10:08
......, start Thu 12/21 9:21

字符串
(b)我想做的是:按日期和时间排序行,但要删除从今天开始的行
(c)下面是实现此函数的Ruby代码

time = Time.new

$mon = time.month
$mday = time.day

# ......

array_tmp = results_all.lines.reject do |x|
    times = x.split(/,/)[1].scan(/\d+/).map(&:to_i)
    times[0] == $mon &&  times[1] == $mday
end

array_tmp.sort_by {|x| x.split(/,/)[1].scan(/\d+/).map(&:to_i)}]


我的问题是:
在Ruby中,是否有更好、更优雅的方法来同时进行过滤和排序?

oxalkeyp

oxalkeyp1#

假设我们得到:

arr = [
  "has , start Mon 10/30 10:08",
  "dog , start Thu 9/24 4:08",4
  "fleas , start Thu 12/21 9:21",
  "Saffi , start Thu 10/29 19:33",
  "My , start Thu 9/7 9:54"
]

个字符
然后可以这样写:

RGX = /
      \d{1,2}   # match 1 or 2 digits
      \/        # match a forward slash
      \d{1,2}   # match 1 or 2 digits
      [ ]+      # match 1 or more spaces
      \d{1,2}   # match 1 or 2 digits
      :         # match a colon
      \d{2}     # match two digits
      $         # match the end of the string
      /x        # invoke free-spacing regex definition mode

x

arr.filter_map do |s|
  dt = string_to_datetime(s)
  [dt, s] unless dt.to_date == today 
end.sort.map(&:last)
  #=> ["My , start Thu 9/7 9:54",
  #    "dog , start Thu 9/24 4:08",
  #    "Saffi , start Thu 10/29 19:33",
  #    "has , start Mon 10/30 10:08"]
def string_to_datetime(str)
  DateTime.strptime(str[RGX], '%m/%d %H:%M')
end

的一种或多种
中间计算

arr.filter_map do |s|
  dt = string_to_datetime(s)
  [dt, s] unless dt.to_date == today 
end
  #=> [[#<DateTime: 2023-10-30T10:08:00+00:00 ((2460248j,36480s,0n),+0s,2299161j)>,
  #     "has , start Mon 10/30 10:08"],
  #    [#<DateTime: 2023-09-24T04:08:00+00:00 ((2460212j,14880s,0n),+0s,2299161j)>,
  #     "dog , start Thu 9/24 4:08"],
  #    [#<DateTime: 2023-10-29T19:33:00+00:00 ((2460247j,70380s,0n),+0s,2299161j)>,
  #     "Saffi , start Thu 10/29 19:33"],
  #    [#<DateTime: 2023-09-07T09:54:00+00:00 ((2460195j,35640s,0n),+0s,2299161j)>,
  #     "My , start Thu 9/7 9:54"]]


显示正在排序的数组。每个元素都是一个两元素数组。第二个元素是正在排序的字符串之一;第一个元素是根据该字符串的月-日-时间表示计算的DateTime示例。排序主要在第一个元素上完成,第二个元素仅用于在两个DateTime示例相等时打破平局。请参阅文档Array#sort。
也可以这样写:

arr.reject do |s|
  string_to_datetime(s).to_date == today 
end.sort_by { |s| string_to_datetime(s) }
  #=> ["My , start Thu 9/7 9:54",
  #    "dog , start Thu 9/24 4:08",
  #    "Saffi , start Thu 10/29 19:33",
  #    "has , start Mon 10/30 10:08"]


这可能会比第一种方法快一些(因为sort_by的块只执行一次计算,尽管string_to_datetime被调用了两次)。
另请参阅Date::today、Escort #filter_map、DateTime::strptime、String#[]和DateTime#to_date。有关DateTime::strptime使用的格式化指令,请参阅Time#strftime。

相关问题