There's a smell to how you're doing this:
Instead of using something like:
range_1 = {"C" => "D"}
range_2 = {"B" => "E"}
I'd opt for using real ranges:
range_1 = 'C' .. 'D'
range_2 = 'B' .. 'E'
Then I could dispense with using array because it's so easy to convert a range to an array of consecutive values.
range_1.to_a # => ["C", "D"]
range_2.to_a # => ["B", "C", "D", "E"]
[*range_1] # => ["C", "D"]
[*range_2] # => ["B", "C", "D", "E"]
If the values in array aren't really consecutive, as in the example, then I'd use index values:
array = ["A", "B", "C", "D", "E"]
range_1 = 2 .. 3
range_2 = 1 .. 4
Which makes it easy to retrieve the values:
array = ["A", "B", "C", "D", "E"]
range_1 = 2 .. 3
range_2 = 1 .. 4
array[range_1] # => ["C", "D"]
array[range_2] # => ["B", "C", "D", "E"]
If you need to use actual values from array as symbolic names for the indexes it becomes harder, similar to what you're doing now, but if you're working with a web front-end it's not too bad. A user's brain and eyes is a nice asset.
Because the use-case isn't well defined we can't really recommend better solutions. I suspect this is a case where you've decided a certain algorithm is the best and now you're trying to make it work, but entropy is setting in as you feel the corner of the room closing in. That's an analysis based on a lot of years of looking at code, not a snap-judgement.
but something like this desn't ["A","B","C","D"]["B".."D"]. I get in '[]': can't convert String into Integer
Something else to consider is that hashes are like arrays, only they allow random access more easily using values_at.
Consider this:
array = %w[a b c d x y z]
hash = Hash[array.map.with_index{ |e, i| [e, i] }]
hash # => {"a"=>0, "b"=>1, "c"=>2, "d"=>3, "x"=>4, "y"=>5, "z"=>6}
The hash doesn't need integers for the values, they could be nils or booleans, and I've used either depending on my needs. I'm using them here to make it more obvious what's happening. The big win is that a hash lets us pull content out in any order, just by specifying what that order is. If it's a range or set of ranges we can still extract values in the order we want.
This is a simple example using a single range:
hash.values_at(*('a' .. 'd')) # => [0, 1, 2, 3]
hash.values_at(*('x' .. 'z')) # => [4, 5, 6]
These are compound range examples:
hash.values_at(*('a' .. 'c'), *('x' .. 'z')) # => [0, 1, 2, 4, 5, 6]
hash.values_at(*('x' .. 'z'), *('a' .. 'c')) # => [4, 5, 6, 0, 1, 2]
Note that in the second on the ranges are reversed, and the values reflect that.
Also notice that the ranges are being broken down into arrays. The arrays could come from anywhere, and as long as the elements match keys in the hash you'll see the values returned in the same order as the array.
("C".."D")instead of a hash with a single key/value. Even a hash withstart: 'C', end: 'D'would be a better way to represent the data.=>notation. It seems I will love the range notation too.