2

I have an array that looks like this:

Array_1 = ["A1", "A2", "A3", "A4", "A5", "B1", "B2", "B3", ..., "Z5"]

I want to create another array with the elements of Array_1 that come after "A5":

Array_2 = ["B1", "B2", "B3", ..., "Z5"]

I have an ugly way that subtracts two arrays to create a third array, but I feel like there is bound to be a classy ruby way of doing something that should be simple. Any help would be amazeballs.

5 Answers 5

7
Array_1 = ["A1", "A2", "A3", "A4", "A5", "B1", "B2", "B3", "Z5"]

Array_1[Array_1.index("A5")+1..-1]
  # => ["B1", "B2", "B3", "Z5"] 

(I suppose we should first compute idx = Array_1.index("A5") to make sure it's non-nil.)

. . .

Another way makes use of Ruby's little-used flip-flop operator:

Array_1.select { |e| e=="A5" .. false ? true : false }[1..-1]
  #=> ["B1", "B2", "B3", "Z5"]

The expression remains false until e=="A5" is true, and remains true until the expression following the two dots is true. Therefore,

Array_1.select { |e| e=="A5" .. false ? true : false }
  #=> ["A5", "B1", "B2", "B3", "Z5"]

[1..-1] is tacked on to return this array without "A5".

The flip-flop operator must be part of a conditional expression, which is why we cannot write:

Array_1.select { |e| e=="A5" .. false }[1..-1]
  #ArgumentError: bad value for range

(for e=="A5" .. false is treated as a normal range).

Sign up to request clarification or add additional context in comments.

2 Comments

I didn't even know that flip-flop operator existed! That's awesome!
Excellent!! The flip-flop operator was just what I was looking for! Thank you for your time and help!
2
Array_1.slice_when{|e| e == "A5"}.to_a.last
# => ["B1", "B2", "B3", ..., "Z5"]

1 Comment

Great! Super sweet and short!
2

How about this?

arr = ["A1", "A2", "A3", "A4", "A5", "B1", "B2", "B3", "Z5"]

p arr.drop_while {|s| s != "A5" }.drop(1)
# => ["B1", "B2", "B3", "Z5"]

1 Comment

This is great! Thanks for the help!
2

.slice_after takes an argument for slicing array

 Array_1.slice_after("A5").to_a.last
    => ["B1", "B2", "B3", "Z5"] 

Comments

1

This creates the array that your are using using a regex match.

array = ('A1'..'Z5').to_a.reject { |el| el.match %r/[A-Z][0, 6-9]/ }

Then to remove the "A(digit)" elements using another regex match.

array_2 = array.select { |el| el.match %r/[B-Z]\d/ }

This has the added benefit of not caring about order, and can separate them regardless.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.