如何将数组拆分成条件较小的数组?

时间:2017-07-07 15:21:19

标签: arrays ruby split

Ruby 2.4。我有一个字符串数组

2.4.0 :007 > arr = ["a", "b", "g", "e", "f", "i"]
 => ["a", "b", "g", "e", "f", "h", "i"]

如何根据条件将数组拆分为较小的数组?我有一个函数 - “contains_vowel”,如果一个字符串包含“a”,“e”,“i”,“o”或“u”,则返回true。我如何使用“contains_vowel”的分隔函数获取一个字符串数组并将其拆分为更小的数组?也就是说,对于上述情况,得到的较小数组的数组将是

[["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

如果较大数组的元素满足条件,则它将成为一个元素的数组。

4 个答案:

答案 0 :(得分:4)

arr = ["a", "b", "g", "e", "f", "i"]

r = /[aeiou]/
arr.slice_when { |a,b| a.match?(r) ^ b.match?(r) }.to_a
   => [["a"], ["b", "g"], ["e"], ["f"], ["i"]]

String#match?在Ruby v2.4中首次亮相。对于早期版本,您可以使用(例如)!!(b =~ r),其中!!将truthy / falsy值转换为true / false。需要进行该转换,因为XOR运算符^提供双重任务:当aba^b truefalse时,它是逻辑XOR, nil2^6 #=> 4,以及操作数为整数时的逐位XOR,例如2.to_s(2) #=> "10"; 6.to_s(2) #=> "110"; 4.to_s(2) #=> "100" function get_menu ($array, $child = FALSE) { $CI =& get_instance(); $str = ''; if (count($array)) { $str .= $child == FALSE ? '<ul class="nav navbar-left navbar-custom">' . PHP_EOL : '</ul>' . PHP_EOL; foreach ($array as $item) { $active = $CI->uri->segment(1) == $item['slug'] ? TRUE : FALSE; if (isset($item['children']) && count($item['children'])) { $str .= $active ? '<li class="dropdown active">' : '<li class="dropdown">'; $str .= '<a class="dropdown-toggle" data-toggle="dropdown" href="' . site_url(e($item['slug'])) . '">' . e($item['title']); $str .= '<b class="caret"></b></a>' . PHP_EOL; $str .= get_menu($item['children'], TRUE); } else { $str .= $active ? '<li class="active">' : '<li>'; $str .= '<a href="' . site_url($item['slug']) . '">' . e($item['title']) . '</a>'; } // Closing tags $str .= '</li>' ; } //add dashboard link to the right of menu for login $str .= '<li>' . '<p class="navbar-text navbar-right"><a `href="admin/dashboard" class="navbar-link"> ADMIN</a></p></li>' . PHP_EOL; $str .= '</ul>' . PHP_EOL; } )。

答案 1 :(得分:3)

另一种给猫皮肤的方法

def contains_vowel(v) 
   v.count("aeiou") > 0
end 
def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    !contains_vowel(before) & !contains_vowel(after)
  end.to_a
end
split_by_substring_with_vowels(arr)
#=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

它的作用:

  • 传递每个连续的2个元素
  • 当其中任何一个包含元音时分裂

您的其他Array

示例
arr = ["1)", "dwr", "lyn,", "18,", "bbe"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe"]]

进一步的例子:(如果你想要连续元素连续元素保持在同一组中)

def split_by_substring_with_vowels(arr)
  arr.chunk_while do |before,after|
    v_before,v_after = contains_vowel(before),contains_vowel(after)
    (!v_before & !v_after) ^ (v_before & v_after)
  end.to_a
end

arr = ["1)", "dwr", "lyn,", "18,", "bbe", "re", "rr", "aa", "ee"]
split_by_substring_with_vowels(arr)
#=> [["1)", "dwr", "lyn,", "18,"], ["bbe", "re"], ["rr"], ["aa", "ee"]]

如果两者都是元音,则检查前后是否都不是元音

答案 2 :(得分:1)

contains_vowel = ->(str) { !(str.split('') & %w|a e i o u|).empty? }

_, result = ["a", "b", "g", "e", "f", "h", "i"].
                 each_with_object([false, []]) do |e, acc|
   cv, acc[0] = acc[0], contains_vowel.(e)
   cv ^ acc.first ? acc.last << [e] : (acc.last[-1] ||= []) << e
end
result
#⇒ [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]

我们在这里做什么:

  1. contains_vowel是一个lambda,用于检查字符串是否包含元音。
  2. 我们减少输入数组,收集最后一个值(包含先前处理过的字符串元音与否)和result
  3. cv ^ acc.first检查它是否是最后一步的元音翻转。
    1. 是否是,我们在结果中附加一个新数组
    2. 是否不是,我们将字符串附加到结果中的最后一个数组。

答案 3 :(得分:1)

我可能会使用chunk,每当其块的值发生变化时,它就会分裂一个数组。 Chunk返回[block_value, [elements]]对的列表,我使用.map(&:last)来获取元素的子列表。

arr = ["a", "b", "g", "e", "f", "h", "i"]

def vowel?(x); %w(a e i o u).include?(x); end

arr.chunk{|x| vowel?(x)}.map(&:last)

=> [["a"], ["b", "g"], ["e"], ["f", "h"], ["i"]]