如何合并受约束的数组中的连续元素?

时间:2017-07-02 16:52:15

标签: arrays ruby string

我使用的是Ruby 2.4。我有一个字符串数组,如果有" - "我想加入连续的元素。它们之间。所以,例如,如果我有

["a", "-", "b", "c"]

我希望结果是

["a - b", "c"]

同样,如果数组是

["a-", "b", "c"]

我希望结果是

["a- b", "c"]

或者如果数组是

["a", "-b", "c", "d"]

我希望结果是

["a -b", "c", "d"]

一个例外是,如果其中一个相邻的令牌已经包含" - ",我不想将它们合并在一起。所以,例如,如果我有

["a", "-", "b-c", "d"]

我希望数组保持为

["a", "-", "b-c", "d"]

卡里帮我提出了这个功能

  def join_some(arr, special_chars_arr)
    arr.drop(1).each_with_object([arr.first]).with_index(1) do |(s,a),i|
      puts "s: #{s} a: #{a.last}"
      if ((special_chars_arr.include?(s[0]) && (i < arr.size - 1 || s.size > 1)) ||
          (special_chars_arr.include?(a.last[-1]) && (i > 1 || a.last.size > 1))) &&
         a.last !~ Regexp.union(special_chars_arr)
        a.last << " #{s}"
      else
        a << s
      end
    end
  end

但问题是如果我的数组是

["a", "-", "b-c"]

调用join_some(arr,[&#34; - &#34;])将事情变成

["a - b-c"]

并且我不想合并相邻的令牌,因为其中一个已经包含短划线。如何修改我的方法来做我想做的事?

2 个答案:

答案 0 :(得分:2)

基于终端元素附加到新阵列

可能有更简洁的方法来表达这一点,但是如果您正在处理String值,那么您可以简单地遍历每个元素以决定是否应将其附加到新数组的最后一个元素,或者添加作为一个单独的元素。例如:

old_array = ["a", "-", "b", "c", "d", "-", "e", "-", "f"]
new_array = []

old_array.each do |value|
  if new_array.last.to_s.end_with? '-' or value.eql? '-'
    new_array.last << value
  else
    new_array.push value
  end
end;

new_array
#=> ["a-b", "c", "d-e-f"]

请注意,即使顺序中有多个短划线或减号,这也非常强大,如果您没有固定的序列长度,这很重要。

答案 1 :(得分:0)

def massage(arr)
  arr.drop(1).each_with_object([arr.first]) do |s,a|
    a <<
    case
    when s == '-'
      s
    when a.last == '-'
      ((a.size > 1) && (a[-2] =~ / - [^ -]+\z|\A[^-]+\z/) && (s !~ /-/)) ?
        [*a.pop(2),s].join(' ') : s
    when a.last.end_with?('-') ^ s.start_with?('-')
      a.pop << ' ' << s
    else
      s
    end
  end
end    

examples = [["a","-","b","c"], ["a-","b","c"], ["a","-b","c","d"],
            ["a","-","b-c","d"], ["-", "a", "b"], ["a", "b", "-"],
            ["a", "-", "b", "-", "c"], ["a", "-", "b", "-", "c", "-d"]]

examples.each { |a| puts "#{a.to_s.ljust(32)}  \#=> #{massage(a)}" }
["a", "-", "b", "c"]              #=> ["a - b", "c"]
["a-", "b", "c"]                  #=> ["a- b", "c"]
["a", "-b", "c", "d"]             #=> ["a -b", "c", "d"]
["a", "-", "b-c", "d"]            #=> ["a", "-", "b-c", "d"]
["-", "a", "b"]                   #=> ["-", "a", "b"]
["a", "b", "-"]                   #=> ["a", "b", "-"]
["a", "-", "b", "-", "c"]         #=> ["a - b - c"]
["a", "-", "b", "-", "c", "-d"]   #=> ["a - b - c -d"]

^是逻辑和按位的XOR运算符。这里两个操作数分别为truefalse(逻辑),因此如果一个操作数为true而另一个操作数为true,则返回false