如何根据每个元素的特征对 ruby 数组中的项目进行分组?
How can I group items in a ruby array based on characteristics of each element?
我有一个通过拆分任何给定单词创建的字母数组。我有一个包含所有五个元音的常量数组,我用它来将字母数组中的每个字母分类为辅音或元音。
VOWELS = ["a","e","i","o","u"]
letters = "compared".split("")
# => ["c", "o", "m", "p", "a", "r", "e", "d"]
word_structure = letters.map { |letter| VOWELS.include?(letter) ? "v" : "c" }
# => ["c", "v", "c", "c", "v", "c", "v", "c"]
我想以某种方式实现两件事:
- 将 "letters" 数组中具有相同 "word_structure" 的相邻字母分组。
- 将这些组和 return 每个可能的 VCV 组合作为另一个数组。 V代表一组所有相邻的元音,C代表一组所有相邻的辅音。
.
groups = ["c", "o", "mp", "a", "r", "e", "d"]
vcv_groups = ["-co", "ompa", "are", "ed-"]
在此示例中,第一个 VCV 组以“-”开头,因为没有第一组元音。接下来的两组完全符合模式,最后一组有另一个“-”,因为没有最后的元音来完成模式。
我尝试过 Enumerable#chunk、Enumerable#partition 和 Enumerable#slice_before,但它们都让我感到困惑。如果有人了解实现此目的的简单方法,我将不胜感激。
"compare"
.split(/([aeiou]+)/).unshift("-").each_cons(3)
.each_slice(2).map{|(v1, c, v2), _| v2 ||= "-"; [v1, c, v2].join}
您可以使用正则表达式来做到这一点(后跟一个混乱的位以根据需要插入连字符):
VOWELS = 'aeiou'
R = /
(?= # begin positive look-ahead
( # begin capture group 1
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\A # match the beginning of the string
) # end non-capture group
[^#{VOWELS}]+ # match one or more consonants
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\z # match end of string
) # end non-capture group
) # end capture group 1
) # end positive lookahead
/x # extended mode
def extract(str)
arr = str.scan(R).flatten
arr[0].insert(0, '-') unless VOWELS.include?(arr[0][0])
arr[-1] << '-' unless VOWELS.include?(arr[-1][-1])
arr
end
extract 'compare' #=> ["-co", "ompa", "are"]
extract 'compared' #=> ["-co", "ompa", "are", "ed-"]
extract 'avacados' #=> ["ava", "aca", "ado", "os-"]
extract 'zzz' #=> ["-zzz-"]
extract 'compaaared' #=> ["-co", "ompaaa", "aaare", "aare", "are", "ed-"]
我有一个通过拆分任何给定单词创建的字母数组。我有一个包含所有五个元音的常量数组,我用它来将字母数组中的每个字母分类为辅音或元音。
VOWELS = ["a","e","i","o","u"]
letters = "compared".split("")
# => ["c", "o", "m", "p", "a", "r", "e", "d"]
word_structure = letters.map { |letter| VOWELS.include?(letter) ? "v" : "c" }
# => ["c", "v", "c", "c", "v", "c", "v", "c"]
我想以某种方式实现两件事:
- 将 "letters" 数组中具有相同 "word_structure" 的相邻字母分组。
- 将这些组和 return 每个可能的 VCV 组合作为另一个数组。 V代表一组所有相邻的元音,C代表一组所有相邻的辅音。
.
groups = ["c", "o", "mp", "a", "r", "e", "d"]
vcv_groups = ["-co", "ompa", "are", "ed-"]
在此示例中,第一个 VCV 组以“-”开头,因为没有第一组元音。接下来的两组完全符合模式,最后一组有另一个“-”,因为没有最后的元音来完成模式。
我尝试过 Enumerable#chunk、Enumerable#partition 和 Enumerable#slice_before,但它们都让我感到困惑。如果有人了解实现此目的的简单方法,我将不胜感激。
"compare"
.split(/([aeiou]+)/).unshift("-").each_cons(3)
.each_slice(2).map{|(v1, c, v2), _| v2 ||= "-"; [v1, c, v2].join}
您可以使用正则表达式来做到这一点(后跟一个混乱的位以根据需要插入连字符):
VOWELS = 'aeiou'
R = /
(?= # begin positive look-ahead
( # begin capture group 1
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\A # match the beginning of the string
) # end non-capture group
[^#{VOWELS}]+ # match one or more consonants
(?: # begin a non-capture group
[#{VOWELS}]+ # match one or more vowels
| # or
\z # match end of string
) # end non-capture group
) # end capture group 1
) # end positive lookahead
/x # extended mode
def extract(str)
arr = str.scan(R).flatten
arr[0].insert(0, '-') unless VOWELS.include?(arr[0][0])
arr[-1] << '-' unless VOWELS.include?(arr[-1][-1])
arr
end
extract 'compare' #=> ["-co", "ompa", "are"]
extract 'compared' #=> ["-co", "ompa", "are", "ed-"]
extract 'avacados' #=> ["ava", "aca", "ado", "os-"]
extract 'zzz' #=> ["-zzz-"]
extract 'compaaared' #=> ["-co", "ompaaa", "aaare", "aare", "are", "ed-"]