如何获得按照拆分结果在拆分中出现的顺序返回的拆分结果?

How do I get the results of a split returned in the order in which they occur in the split?

我正在使用 Ruby 2.4。我正在尝试拆分数组中的元素。我想要的是用我的拆分结果形成等效数组。我希望拆分的第一部分是第一个数组,拆分的第二部分是第二个数组。所以我有

data_col = ["mm a", "nn b", "nn a"]
arr1, arr2 = data_col.map do |x| 
  if x
    a, b, c = x.partition(/(^|[[:space:]]+)[ab]$/i)
    [b.strip, a + c] 
  else
      [nil, nil]
  end
end.transpose
 #=> [["a", "b", "a"], ["mm", "nn", "nn"]]

问题是,拆分工作正常,但数组正在颠倒。我希望 ["mm", "nn", "nn"] 成为数组中的第一个元素。如何重写以便正确返回数组——也就是说,拆分的第一部分在第一个数组中,拆分的第二部分在第二个数组中?

data_col = ["mm a", "nn b", "nn a"]
arr1, arr2 = data_col.map do |x| 
  a, b, c = x.partition(/(^|[[:space:]]+)[ab]$/i)
  [a + c, b.strip] # <=================== switched b.strip and a+b
end.transpose
#=> [["mm", "nn", "nn"], ["a", "b", "a"]]

我删除了 if x 条件,因为无法在您的 mapping 中从 if x 获取 false :)

我认为你甚至不需要使用带有正则表达式的分区来获得 o/p,你可以简单地使用带有拆分和转置的映射来获得相同的 o/p 而且它非常快与使用正则表达式进行分区相比。下面是5秒的简单基准测试,

require 'benchmark/ips'

data_col = ["mm a", "nn b", "nn a"]

Benchmark.ips do |x|
  x.config(time: 5, warmup: 2)
  x.report('REGEXP') do
    arr1, arr2 = data_col.map do |xx|
      a, b, c = xx.partition(/(^|[[:space:]]+)[ab]$/i)
      [a + c, b.strip]
    end.transpose 
  end

  x.report('MAP SPLIT') do
    arr1, arr2 = data_col.map do |xx|
      xx.split(' ').map(&:strip)
    end.transpose
  end
  x.compare!
end

下面是IPS对比,

Warming up --------------------------------------
              REGEXP    16.985k i/100ms
           MAP SPLIT    26.771k i/100ms
Calculating -------------------------------------
              REGEXP    190.220k (± 4.5%) i/s -    951.160k in   5.012963s
           MAP SPLIT    303.243k (± 3.5%) i/s -      1.526M in   5.040226s

Comparison:
           MAP SPLIT:   303243.1 i/s
              REGEXP:   190219.6 i/s - 1.59x  slower

您可以看到带分割的地图正在执行 303243.1 i/s 其中带正则表达式的分区正在执行 190219.6 i/s.因此,使用分割的映射 1.59 倍 比使用正则表达式的分割快