breaking up an array

October 13th, 2007

There’s probably a better way to name this, but whattayagonna do?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Array
  # split an array based on block
  def divorce
    mom = []
    dad = []
    for i in 0...size
      value = self[i]
      if yield(value)
        mom << value
      else
        dad << value
      end
    end
    return [mom, dad]
  end
end

Examples:

1
2
3
4
5
6
7
8
9
10
>> strings, non_strings = [5,6,"aaa", 7, "ccc"].divorce { |element| element.is_a? String }
=> [["aaa", "ccc"], [5, 6, 7]]

>> longs, shorts = ["Hello.", "Hi, how are you today?", "Great!"].divorce { |st| st.size > 10 }
=> [["Hi, how are you today?"], ["Hello.", "Great!"]]

>> mults_of_3, non_mults_of_3 = (1..10).to_a.divorce { |n| n % 3 == 0 }
=> [[3, 6, 9], [1, 2, 4, 5, 7, 8, 10]]
>> mults_of_2, non_mults_of_2_or_3 = non_mults_of_3.divorce { |n| n % 2 == 0 }
=> [[2, 4, 8, 10], [1, 5, 7]]

I use it mostly for breaking up collections of ActiveRecord objects, where I want to process them differently depending on some attribute, but don't want to make multiple database/find calls or select/detect calls.

3 Responses to “breaking up an array”

  1. Andrew Grim Says:

    There is in fact a better way, and it’s already in ruby, partition”.

  2. Andrew Grim Says:

    Hmm..let me try that again

  3. Jason L. Says:

    Ah, there we go. There’s always a way in ruby – sometimes it’s just harder to find it. Thanks for the tip.

Sorry, comments are closed for this article.