Программирование на языке Ruby.

8.3.3. Метод partition.

Как говорится, «в мире есть два сорта людей: те, что делят людей по сортам, и те, что не делят». Метод partition относится не к людям (хотя мы можем представить их в Ruby как объекты), но тоже делит набор на две части.

Если при вызове partition задан блок, то он вычисляется для каждого элемента набора. В результате создаются два массива: в первый попадают элементы, для которых блок вернул значение true, во второй — все остальные. Метод возвращает массив, двумя элементами которого являются эти массивы.

Nums = [1, 2, 3, 4, 5, 6, 7, 8, 9].

Odd_even = nums.partition {|x| x % 2 == 1 }.

# [[1,3,5,7,9],[2,3,4,6,8]].

Under5 = nums.partition {|x| x < 5 }.

# [[1,2,3,4],[5,6,7,8,9]].

Squares = nums.partition {|x| Math.sqrt(x).to_i**2 == x }.

# [[1,4,9], [2,3,5,6,7,8]].

Если нужно разбить набор больше чем на две группы, придется написать собственный метод. Я назвал его classify по аналогии с методом из класса Set.

Module Enumerable.

 def classify(&block).

  hash = {}.

  self.each do |x|

   result = block.call(x).

   (hashfresult] ||= []) << x.

  end.

  hash.

 end.

End.

Nums = [1,2,3,4,5,6,7,8,9].

Mod3 = nums.classify {|x| x % 3 }.

# { 0=>[3,6,9], 1=>[1,4,7], 2=>[2,5,8] }.

Words = %w( area arboreal brick estrous clear donor ether filial.

Patina ].

Vowels = words.classify {|x| x.count("aeiou") }.

# {1=>["brick"], 2=>["clear", "donor", "ether"],

#  3=>["area", "estrous", "filial", "patina"], 4=>["arboreal"]}.

Initials = words.classify {|x| x[0..0] }.

# {"a"=>["area", "arboreal"], "b"=>["brick"], "c"=>["clear"],

#  "d"=>["donor"], "p"=>["patina"], "e"=>["estrous", "ether"],

#  "f"=>["filial"]}.