我有一个doc_count数组,其中包含带有日期(年-月-日)的字符串。
我想通过删除“重复项”将doc_count转换为目标,这意味着我想保留较长的日期字符串,而删除较短的日期字符串。
“ 2019-02-01:186904”而不是“ 2019-02-01”
doc_count = [
["foo", "2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"],
["bar", "2019-01-01: 8876", "2019-04-01: 8694", "2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"]
]
goal = [
["foo", "2019-01-01", "2019-02-01: 186904", "2019-03-01: 196961", "2019-04-01"],
["bar", "2019-01-01: 8876", "2019-02-01", "2019-03-01", "2019-04-01: 8694"]
]
month.match(/^\d{4}-\d{2}-\d{2}/) && month.include?(': ') ?
month.match(/^\d{4}-\d{2}-\d{2}/)[0] : month
my_attempt = doc_count.each do |topic|
topic.each do |el|
topic.delete(el) if el == string_to_month(el)
end
end
由于某种原因,我的尝试未能生成与目标相同的数组。
2.6.3 (main):0 > my_attempt
=> [
[0] [
[0] "foo",
[1] "2019-02-01: 186904",
[2] "2019-03-01: 196961",
[3] "2019-02-01",
[4] "2019-04-01"
],
[1] [
[0] "bar",
[1] "2019-01-01: 8876",
[2] "2019-04-01: 8694",
[3] "2019-02-01",
[4] "2019-04-01"
]
]
我怎样才能解决这个问题?非常感谢你!
doc_count = [
["foo", "2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01",
"2019-02-01", "2019-03-01", "2019-04-01"],
["bar", "2019-01-01: 8876", "2019-04-01: 8694", "2019-01-01",
"2019-02-01", "2019-03-01", "2019-04-01"]
]
我们可能会写
def doit(doc_count)
doc_count.map do |arr|
date_strings, other_strings =
arr.partition { |s| s.match? /\A\d{4}-\d{2}-\d{2}(?::|\z)/ }
other_strings + select_dates(date_strings)
end
end
select_dates
一种尚待构建的方法在哪里。
的计算doc_count[0]
如下:
arr = doc_count[0]
#=> ["foo", "2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01",
# "2019-02-01", "2019-03-01", "2019-04-01"]
date_strings, other_strings =
arr.partition { |s| s.match? /\A\d{4}-\d{2}-\d{2}(?::|\z)/ }
#=> [["2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01",
# "2019-02-01", "2019-03-01", "2019-04-01"], ["foo"]]
date_strings
#=> ["2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01",
# "2019-02-01", "2019-03-01", "2019-04-01"]
other_strings
#=> ["foo"]
的第二个元素的计算doc_count
类似。参见Enumerable#partition。
我现在将给出两种构造方法的方法select_dates
,第一种方法效率更高,第二种方法可以说更直接。
使用Hash#update(aka merge!
)的形式,该形式采用一个块来确定要合并的两个哈希中存在的键的值
def select_dates(date_strings)
date_strings.each_with_object({}) do |s,h|
h.update(s[0, 10]=>s) { |_,o,n| n.size >= o.size ? n : o }
end.values
end
请参阅块变量的解释商务部_
,o
和n
(_
--a有效的局部变量-用于第一块变量告诉读者,这是不是在块计算中使用)。对于date_strings
以上给出的doc_count[0]
select_dates(date_strings)
#=> ["2019-02-01: 186904", "2019-03-01: 196961", "2019-01-01",
# "2019-04-01"]
计算如下。
enum = date_strings.each_with_object({})
#=> #<Enumerator: ["2019-02-01: 186904", "2019-03-01: 196961",
# "2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01"
# ]:each_with_object({})>
s,h = enum.next
#=> ["2019-02-01: 186904", {}]
s #=> "2019-02-01: 186904"
h #=> {}
key = s[0, 10]
#=> "2019-02-01"
h.update(key=>s) { |_,o,n| n.size >= o.size ? n : o }
#=> {"2019-02-01"=>"2019-02-01: 186904"}
s,h = enum.next
#=> ["2019-03-01: 196961", {"2019-02-01"=>"2019-02-01: 186904"}]
key = s[0, 10]
#=> "2019-03-01"
h.update(key=>s) { |_,o,n| n.size >= o.size ? n : o }
#=> {"2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961"}
s,h = enum.next
#=> ["2019-01-01", {"2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961"}]
key = s[0, 10]
#=> "2019-01-01"
h.update(key=>s) { |_,o,n| n.size >= o.size ? n : o }
#=> {"2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961", "2019-01-01"=>"2019-01-01"}
s,h = enum.next
#=> ["2019-02-01", {"2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961", "2019-01-01"=>"2019-01-01"}]
key = s[0, 10]
#=> "2019-02-01"
h.update(key=>s) { |_,o,n| n.size >= o.size ? n : o }
#=> {"2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961", "2019-01-01"=>"2019-01-01"}
对于生成的前三个元素enum
并将其传递给该块,update
的块不会起作用,因为要合并的两个哈希(h
和{ key=>s }
)没有公共密钥。对于第四元件("2019-02-01")
,其存在于被合并两个哈希值,我们推迟到块比较h["2019-02-01"].size #=> "2019-02-01: 186904".size => 18
用"2019-02-01".size #=> 10
。由于前者较大,因此将其保留为"2019-02-01"
in的值h
。的其余计算update
结果类似,得出:
h #=> ["2019-02-01"=>"2019-02-01: 186904",
# "2019-03-01"=>"2019-03-01: 196961", "2019-01-01"=>"2019-01-01",
# "2019-04-01"=>"2019-04-01" }
最后一步是从此哈希(h.values
)中提取值。
def select_dates(date_strings)
date_strings.sort_by(&:size).reverse.uniq { |s| s[0, 10] }
end
对于date_strings
以上给出的doc_count[0]
select_dates(date_strings)
#=> ["2019-03-01: 196961", "2019-02-01: 186904", "2019-04-01",
# "2019-01-01"]
计算如下。
a = date_strings.sort_by(&:size)
#=> ["2019-01-01", "2019-02-01", "2019-03-01", "2019-04-01",
# "2019-02-01: 186904", "2019-03-01: 196961"]
b = a.reverse
#=> ["2019-03-01: 196961", "2019-02-01: 186904", "2019-04-01",
# "2019-03-01", "2019-02-01", "2019-01-01"]
b.uniq { |s| s[0, 10] }
#=> ["2019-03-01: 196961", "2019-02-01: 186904", "2019-04-01",
# "2019-01-01"]
请注意,Array#uniq
状态文档“self
按顺序遍历,并保留第一个匹配项。”。表达方式
sort_by(&:size).reverse
可以替换为
sort_by { |s| -s.size }
但据报道,我使用的速度往往更快。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句