5
\$\begingroup\$

Given the task of having to return an array that alternately takes elements from two arrays, what would be most Ruby way of completing the task? As of now, I have this code, but it doesn't feel very elegant.

def alternateTake (a, b)
 raise ArgumentError, "Unequal length" if a.length != b.length
 build = []
 (0..a.length-1).each do |x|
 build << (x.even? ? a[x] : b[x])
 end
 build
end

Example input & output:

method([1, 4, 3, 7], [1, 4, 2, 33]) = [1, 4, 3, 33]
method([98, 12, 41], [35, 22, 14]) = [98, 22, 41]
method([12, 33], [66, 45, 3]) = ERROR
asked May 16, 2016 at 22:30
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$

This one-liner should be what you're looking for:

def alternate_take(xs, ys) 
 raise ArgumentError, "Unequal length" if xs.length != ys.length
 xs.zip(ys).map.with_index{|(x,y),i| i.even? ? x : y} 
end

Follow Up

Tokland's answer to OP's followup about a solution without indexes is really clever. Here's another variation, which I don't like as much as the index version, but it answers the question:

def alternate_take(xs, ys) 
 raise ArgumentError, "Unequal length" if xs.length != ys.length
 xs.zip(ys).reduce([]){|m,(x,y)| m + (m.size.even? ? [x] : [y])} 
end
answered May 16, 2016 at 22:51
\$\endgroup\$
7
  • \$\begingroup\$ Looks good. Some details: maybe use unless instead of if, give plural names to a and b (maybe: xs, ys) and unpack the pair |(x, y), idx| ... \$\endgroup\$ Commented May 16, 2016 at 22:55
  • \$\begingroup\$ Is there any way to use iterators or something like that and avoid using indices? \$\endgroup\$ Commented May 16, 2016 at 22:57
  • \$\begingroup\$ @tokland, Both good suggestions, edited. \$\endgroup\$ Commented May 16, 2016 at 23:01
  • 2
    \$\begingroup\$ @Michael. A lot of ways, for example: xs.zip(ys, [true, false].cycle).map { |x, y, take_x| take_x ? x : y }. Not that there is anything wrong with using with_index. \$\endgroup\$ Commented May 16, 2016 at 23:01
  • \$\begingroup\$ Jonah, the second version is so horrible.. I don't think it's worth it. Children watching! :) There is nothing wrong with using with_index, it's not the same than accessing the array by indexes (which is indeed ugly). \$\endgroup\$ Commented May 17, 2016 at 7:23

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.