问题
我有一个由“块”分隔的数组。每个不可见块都以一个数字 5 的字母开始,并在另一个数字 5 的字母出现时结束。
- a = [
- "F5","a4","g4","F5","a4","d4","F5","a4","g4","e3",
- "H5","a4",
- "Y5","a4","d4","Y5","g4","c3"
- ]
复制代码
在这个数组中,有 3 个“块”。如下所示。
我想要得到的是每个块(不是数组本身)中每个元素的序列(从 1 到 N),其中输出是:
- b = [
- ["F5",1],["a4",1],["g4",1],["F5",2],["a4",2],["d4",1],["F5",3],["a4",3],["g4",2],["e3",1],
- ["H5",1],["a4",1],
- ["Y5",1],["a4",1],["d4",1],["Y5",2],["g4",1],["c3",1]
- ]
复制代码
在我目前的尝试中,我只得到每个元素的计数,而不是序列。如何做呢?谢谢
- a = [
- "F5","a4","g4","F5","a4","d4","F5","a4","g4","e3",
- "H5","a4",
- "Y5","a4","d4","Y5","g4","c3"
- ]
- b = []
- a.each{|v|
- b.push([v,a.count(v)])
- }
- => [
- ["F5", 3], ["a4", 5], ["g4", 3], ["F5", 3], ["a4", 5], ["d4", 2], ["F5", 3], ["a4", 5], ["g4", 3], ["e3", 1],
- ["H5", 1], ["a4", 5],
- ["Y5", 2], ["a4", 5], ["d4", 2], ["Y5", 2], ["g4", 3], ["c3", 1]
- ]
复制代码
回答
我们得到数组
- a = ["F5","a4","g4","F5","a4","d4","F5","a4","g4","e3",
- "H5","a4","Y5","a4","d4","Y5","g4","c3"]
复制代码
这个问题可以看成有两个步骤,第一个是将a转换为
- arr = [["F5","a4","g4","F5","a4","d4","F5","a4","g4","e3"],
- ["H5","a4"], ["Y5","a4","d4","Y5","g4","c3"]]
复制代码
第二步是从 arr 构造所需的数组。
第1步
我了解将 a 转换为 arr 的规则如下。
arr
YZ
/[A-Z]\d/
5
一种
b
arr
一种
一种
一种
一种
b
/[A-Z]\d/
b
我们可以写
- frst = a.first
- arr = a.slice_before do |s|
- (s[0].match?(/[A-Z]/) && s[0] != frst[0] && s[1] == frst[1]) ?
- (frst = s) : false
- end.to_a
- #=> [["F5", "a4", "g4", "F5", "a4", "d4", "F5", "a4", "g4", "e3"]],
- # ["H5", "a4"], ["Y5", "a4", "d4", "Y5", "g4", "c3"]]
复制代码
请参阅前面的可枚举切片。
第2步
我们现在可以将 arr 转换为所需的数组,如下所示。
- arr.map do |e|
- h = Hash.new(0)
- e.map { |s| [s, h[s] += 1] }
- end
- #=> [[["F5", 1], ["a4", 1], ["g4", 1], ["F5", 2], ["a4", 2], ["d4", 1],
- # ["F5", 3], ["a4", 3], ["g4", 2], ["e3", 1]],
- # [["H5", 1], ["a4", 1]],
- # [["Y5", 1], ["a4", 1], ["d4", 1], ["Y5", 2], ["g4", 1], ["c3", 1]]]
复制代码
这里 Hash::new 用于创建一个默认值为 0 的空 Hash h。这意味着如果 h 没有键,k 返回零。因为 h[k] 可以看作
h[k] += 1
当 h[k] = h[k] + 1 没有键时,右侧的 h[k] 返回 1 。另一种写法是
H
请参阅哈希提取。
|