我有一个字符串数组
foo
我想通过以字母开头的空格连续元素加入,至少包含两个字符,并且不包含空格。将该逻辑应用于上述将产生
["123", "a", "cc", "dddd", "mi hello", "33"]
同样,如果我的数组是
["123", "a", "cc dddd", "mi hello", "33"]
我希望结果是
["mmm", "3ss", "foo", "bar", "foo", "55"]
我该如何操作?
答案 0 :(得分:4)
有很多方法可以解决这个问题;红宝石是一种表达力很强的语言。显示到目前为止已经尝试过的内容对您来说是最有益的,这样我们就可以帮助调试/修复/改进您的尝试。
例如,这是我提出的一种可能的实现方式:
def combine_words(array)
array
.chunk {|string| string.match?(/\A[a-z][a-z0-9]+\z/i) }
.flat_map {|concat, strings| concat ? strings.join(' ') : strings}
end
combine_words(["aa", "b", "cde", "f1g", "hi", "2j", "l3m", "op", "q r"])
# => ["aa", "b", "cde f1g hi", "2j", "l3m op", "q r"]
请注意,我有点不清楚如何解释您的要求:
以字母开头,至少有两个字符,并且不包含空格
字符串可以包含标点符号吗?强调? Utf-8字符?我把它用来表示"只有a-z,A-Z或0-9",但你可能想调整它。
对您的要求的字面解释可能是:/\A[[:alpha:]][^ ]+\z/
,但我怀疑这不是您的意思。
<强>解释强>
Enumerable#chunk
将遍历数组并按块的响应值收集术语。在这种情况下,它会找到与所需正则表达式匹配/不匹配的顺序元素。String#match?
检查字符串是否与模式匹配,并返回布尔响应。请注意,如果您使用ruby v2.3
或更低版本,则需要一些解决方法,例如!!string.match
,以强制执行布尔响应。Enumerable#flat_map
遍历每个&#34;结果&#34;,如果需要,连接字符串,并展平结果以避免返回任何嵌套数组。这是另一个类似的解决方案:
def word?(string)
string.match?(/\A[a-z][a-z0-9]+\z/i)
end
def combine_words(array)
array
.chunk_while {|x, y| word?(x) && word?(y)}
.map {|group| group.join(' ')}
end
或者,这是一个更低的技术&#34;解决方案 - 仅使用更多基本语言功能。 (我在这里重复使用相同的word?
方法):
def combine_words(array)
previous_was_word = false
result = []
array.each do |string|
if previous_was_word && word?(string)
result.last << " #{string}"
else
result << string
end
previous_was_word = word?(string)
end
result
end
答案 1 :(得分:2)
您可以使用Enumerable#chunk。
def chunk_it(arr)
arr.chunk { |s|
(s.size > 1) && (s[0].match?(/\p{Alpha}/)) && !s.include?(' ')}.
flat_map { |tf,a| tf ? a.join(' ') : a }
end
chunk_it(["123", "a", "cc", "dddd", "mi hello", "33"])
#=> ["123", "a", "cc dddd", "mi hello", "33"]
chunk_it ["mmm", "3ss", "foo", "bar", "foo", "55"]