switch_around
require 'enumerator' # Returns an object of the argument's class with each_slice of 2 switched around. # Works on any object that mixes in #each # # Examples: # switch_around("foo!") #=> of!o # switch_around((1..10).to_a) #=> [2, 1, 4, 3, 6, 5, 8, 7, 10, 9] def switch_around(data) switched_data = data.class.new # When appending to a string ints will have #chr called on them, so protect against # error about sending a message to nil. b will only be nil when the collection is # an odd length. Of course, this creates a bug. For example we could have an Array with # embedded nils, so we must also check if it is a String (again...) switch_proc = lambda do |a,b| switched_data << b unless b.nil? and data.is_a?(String) switched_data << a end # String#each enumerates over lines, so we must change it to enumerate over bytes. if data.is_a?(String) data.to_enum(:each_byte).each_slice(2) { |a,b| switch_proc.call(a, b) } else data.each_slice(2) { |a,b| switch_proc.call(a,b) } end switched_data end