如何根据每个元素的特征对ruby数组中的项进行分组?

时间:2015-10-22 06:29:52

标签: arrays ruby enumerable

我有一个通过拆分任何给定单词创建的字母数组。我有五个元音的常数数组,我用它来将字母数组中的每个字母分类为辅音或元音。

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"]

我想以某种方式实现两件事:

  1. 将相邻字母分组在"字母"具有相同" word_structure"。
  2. 的数组
  3. 获取这些组并将每个可能的VCV组合作为另一个阵列返回。 V表示所有相邻元音的分组,C表示所有相邻辅音的分组。
  4.  groups = ["c", "o", "mp", "a", "r", "e", "d"]
    
     vcv_groups = ["-co", "ompa", "are", "ed-"]
    

    在此示例中,第一个VCV组以" - "开头。因为没有第一组元音。接下来的两个分组完全适合该模式,而最后一个分组具有另一个" - "因为没有最终的元音来完成模式。

    我已经尝试过Enumerable#chunk,Enumerable#partition和Enumerable#slice_before,但他们只是让我感到困惑。如果有人理解实现这一目标的简单方法,我将非常感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

你可以使用正则表达式(后面跟一个杂乱的位来插入连字符):

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-"]

答案 1 :(得分:1)

"compare"
.split(/([aeiou]+)/).unshift("-").each_cons(3)
.each_slice(2).map{|(v1, c, v2), _| v2 ||= "-"; [v1, c, v2].join}