Arrays 在Ruby中,如何根据条件合并数组中的连续标记?
这是Ruby 2.4的一部分。我有一个字符串数组,如果连续元素以特殊字符开头或结尾,我想融合它们。例如,如果我的特殊字符是“&”,我有一个数组Arrays 在Ruby中,如何根据条件合并数组中的连续标记?,arrays,ruby,merge,Arrays,Ruby,Merge,这是Ruby 2.4的一部分。我有一个字符串数组,如果连续元素以特殊字符开头或结尾,我想融合它们。例如,如果我的特殊字符是“&”,我有一个数组 ["a &", "b", "c", "d"] 我希望结果是 ["a & b", "c", "d"] ["a & b", "c"] ["a & b", "c"] 类似地,如果数组是 ["a", "&", "b", "c"] ["&", "b", "c"] 我希望结果是 ["a & b",
["a &", "b", "c", "d"]
我希望结果是
["a & b", "c", "d"]
["a & b", "c"]
["a & b", "c"]
类似地,如果数组是
["a", "&", "b", "c"]
["&", "b", "c"]
我希望结果是
["a & b", "c", "d"]
["a & b", "c"]
["a & b", "c"]
如果数组是
["a", "& b", "c"]
我希望结果是
["a & b", "c", "d"]
["a & b", "c"]
["a & b", "c"]
但是,如果数组是
["a", "&", "b", "c"]
["&", "b", "c"]
结果应该是
["&", "b", "c"]
因为在我的特殊角色之前没有非特殊元素。所以我尝试了这个方法
2.4.0 :012 > words = ["a", "&", "b", "d"]
=> ["a", "&", "b", "d"]
2.4.0 :013 > SPECIAL_TOKENS = %w(&).freeze
=> ["&"]
2.4.0 :014 > words = words.chunk_while { |i, _| i.end_with?(*SPECIAL_TOKENS) }.map(&:join)
=> ["a", "&b", "d"]
但正如您所看到的,它并没有将中的第一个元素与其余元素融合(而且我在“&”和“b”之间丢失了一个空格)。我是否可以对上述内容进行任何调整,以使其如我所期望的那样工作?这是一个相当冗长的问题,但通过了您的测试。该方法将数组和特殊字符作为参数。初始的
join.split.reject.map
将数组“标准化”为剥离的单个元素,除了两边都有空格的特殊字符。然后我们申请两次
这里有两种方法。我假设,与示例中一样,数组中没有任何元素(字符串)以空格开头或结尾 #1
def join_some(arr, join_ch='&')
arr.drop(1).each_with_object([arr.first]).with_index(1) do |(s,a),i|
if (s[0] == join_ch && (i < arr.size - 1 || s.size > 1)) ||
(a.last[-1] == join_ch && (i > 1 || a.last.size > 1))
a.last << " #{s}"
else
a << s
end
end
end
join_some ["a", "&", "b", "d"] #=> ["a & b", "d"]
join_some ["a", "& b", "c"] #=> ["a & b", "c"]
join_some ["&", "b", "c"] #=> ["&", "b", "c"]
join_some ["a", "b", "&"] #=> ["a", "b", "&"]
join_some ["a", "&", "b", "&", "c"] #=> ["a & b & c"]
join_some ["a", "& b &", "c"] #=> ["a & b & c"]
join_some ["&", "& b", "c"] #=> ["& & b", "c"]
join_some [" &", "b", "c"] #=> [" & b", "c"]
join_some ["&", "&", "&"] #=> ["& & &"]
join_some ["a", "+ b", "+ c"], "+" #=> ["a + b + c"]
对于上述10个示例,该方法给出的结果与第一种方法相同。下面以自由间距模式表示正则表达式,并附有解释性注释。这里join#ch=>“&”
和split#ch=>\x00
r = /
(?<= # begin positive lookbehind
\A # match the beginning of the string
. # match any char
| # or
[^#{join_ch}] # match any char other than the join char
) # end positive lookbehind
#{split_ch} # match split char
(?= # begin a positive lookahead
[^#{join_ch}] # match any char other than the join char
| # or
. # match any char
\z # match end of the string
) # end positive lookahead
/x # free-spacing regex definition mode
#=> (?<= # begin positive lookbehind
# \A # match the beginning of the string
# . # match any char
# | # or
# [^&] # match any char other than the join char
# ) # end positive lookbehind
# \x00 # match split char
# (?= # begin a positive lookahead
# [^&] # match any char other than the join char
# | # or
# . # match any char
# \z # match end of the string
# ) # end positive lookahead
# /x # free-spacing regex definition mode
r=/
(?(我的解决方案不使用特殊字符,在我看来,最不令人惊讶的是,它
- 忽略字符串开头或结尾的额外尾随(&s)
- 单独保留连续的(分开的)&s(可能需要在它们之间插入某些内容)
- 与&&、&&&、&hello&、
代码:
当您的第二个项目以&
开头时,您为什么要使用end\u with?
?只需一个指针即可:假设您希望这两个元素[“a”、“&b”]
最终成为元素“a&b”
(即具有额外的空间)您还需要能够修改元素。因此,仅使用chunk\u而是无法实现这一点的。也许可以尝试编写一些伪代码来描述这应该如何工作,然后用Ruby编写它,一旦您有了可以工作的东西,您就可以要求提供使其更地道的技巧了。那么['a'、'&b&'、'c']
?['a'、'&b'、'&c']
?、、、['a'、'&','b'、'&','c']
?