问题
I'm using Ruby 2.4. I have an array with string data elements, that look like
["a word1 word2", "b eff", "a idaho orange", "new old shoe", "b mars", ...]
I want to form two arrays from the above, applying a function (.split(/^(a|b)[[:space]]*/i
) to each element of the array. However, I can't figure out how to form two separate arrays. The following
arr.map{ |x| x.split(/^(a|b)[[:space]]*/i) }
only results in a single array and has a blank element in front of each element. Ideally, I'd like the output to be two arrays like
["a", "b", "a", "", "b", ...]
["word1 word2", "eff", "idaho orange", "new old shoe", "mars", ...]
回答1:
Try this
arr.map { |x| a, b, c = x.partition(/^[ab]\s+/); [b.strip, a + c] }.transpose
How does this work?
partition
splits a string into before-match, match and post-matchb.strip
is the match without trailing whitespacea + c
is either the full string (if there was no match the full string is in before-match) or the post-match[..., ...]
creates a tuple, hence creating an array of tupletranspose
switches the rows and columns of a 2D array
回答2:
Regex only
This is the shortest I could find :
a1, a2 = arr.map{ |x| x.match(/((?:^[ab](?= ))?) *(.*)/).captures}.transpose
This example now works with "activity"
or "ball"
. It checks if a space follows directly after a
or b
at the beginning of the string.
Split and logic
Another variant would be :
a1, a2 = arr.map do |x|
parts = x.split(/(?<=^a|^b) +/)
parts.unshift('') if parts.size == 1
parts
end.transpose
来源:https://stackoverflow.com/questions/41795017/how-do-i-apply-a-function-to-an-array-and-form-two-separate-arrays