从数组中选择一个键值对



我有一个看起来像这样的数组

[
"---n",
":date: 2018-07-31n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-01n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-22n  :estimated_hours: 4.0n  :remaining_hours: 0.0n "
]

我想选择键":date"的所有值。我读到我可以使用Enumerable#select,但我不知道该怎么做。谁能帮忙?

arr = ["---n",
":date: 2018-07-31n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-01n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-22n  :estimated_hours: 4.0n  :remaining_hours: 0.0n "]

arr.join.scan(/:date: (d{4}-d{2}-d{2})/).flatten
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]

arr.join.scan(/(?<=:date: )d{4}-d{2}-d{2}/).flatten
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]

(?<=:date: )是一个积极的回头人,

arr.join.gsub(/(?<=:date: )d{4}-d{2}-d{2}/).to_a
#=> ["2018-07-31", "2018-08-01", "2018-08-22"]

最后一个选项看起来有点奇怪,因为我仅使用gsub来创建一个生成与正则表达式匹配的枚举器。这是当 String#gsub 只有一个参数而没有块时的结果。在这种情况下,名称"gsub"具有误导性,因为没有用其他字符串替换字符串。想想这种形式的方法被称为match_all。我发现这种形式的gsub有很多用途。

可以将String#[]与正则表达式参数和正面回望一起使用:

input.flat_map { |e| e[/(?<=:date:s).*/] }.compact
#⇒ ["2018-07-31", "2018-08-01", "2018-08-22"]

由于这看起来很像YAML(尽管它需要一点消毒(,我会选择:

a = [
"---n",
":date: 2018-07-31n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-01n  :estimated_hours: 4.0n  :remaining_hours: 4.0n ",
":date: 2018-08-22n  :estimated_hours: 4.0n  :remaining_hours: 0.0n "
].map(&:rstrip)
require 'yaml'
data = a[1..-1].map {|s| YAML.load(s.gsub("  ", ""))}
#=> [
#  {:date=>#<Date: 2018-07-31 ((2458331j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>4.0}, 
#  {:date=>#<Date: 2018-08-01 ((2458332j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>4.0}, 
#  {:date=>#<Date: 2018-08-22 ((2458353j,0s,0n),+0s,2299161j)>, :estimated_hours=>4.0, :remaining_hours=>0.0}]
data.map {|h| h[:date] } 
#=> [#<Date: 2018-07-31 ((2458331j,0s,0n),+0s,2299161j)>, 
#     #<Date: 2018-08-01 ((2458332j,0s,0n),+0s,2299161j)>, 
#     #<Date: 2018-08-22 ((2458353j,0s,0n),+0s,2299161j)>]

希望这有帮助

data = ["---n", ":date: 2018-07-31n :estimated_hours: 4.0n :remaining_hours: 4.0n ", ":date: 2018-08-01n :estimated_hours: 4.0n :remaining_hours: 4.0n ", ":date: 2018-08-22n :estimated_hours: 4.0n :remaining_hours: 0.0n "]
DATE_REGEX = /:date:s(.*)n/
dates = data.map do |record|
record.match(DATE_REGEX)[1] if record.match(REGEX)
end.compact

最新更新