2013-04-05 1 views
7
# this code works 
list = (0..20).to_a 
# => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 

odd = list.select { |x| x.odd? } 
# => [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] 

list.reject! { |x| x.odd? } 
# => [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 

# but can i emulate this type of functionality with an enumerable method? 
set = [1,5,10] 
# => [1, 5, 10] 
one, five, ten = set 
# => [1, 5, 10] 
one 
# => 1 
five 
# => 5 
ten 
# => 10 

# ------------------------------------------------ 
# method I am looking for ? 
list = (0..20).to_a 
odd, even = list.select_with_reject { |x| x.odd? } 
# put the matching items into the first variable 
# and the non-matching into the second 
+0

построен в методах хорош, но вы против добавления своего собственного метода на 'Array', что бы сделать это? – MrDanA

+0

Да, я думал о том, что арка для обезьян, чтобы добавить его, похоже, что-то рубин, возможно, уже встроил, но ничего не видел в документах – house9

ответ

11

Конечно, вы можете сделать:

odd, even = list.partition &:odd? 
+0

awesome - thanks; Интересно, что это проявляется в перечислимых документах - http://ruby-doc.org/core-1.9.2/Enumerable.html, но не в массиве? – house9

+1

@ house9 Enumerable - это mixin, поэтому многие классы могут его использовать. Хэши тоже используют их. – MrDanA

+0

Это потому, что он определен в 'Enumerable', но не на' Array'. Это называется * наследованием * и является одной из фундаментальных концепций Ruby и многих других языков, а не только объектно-ориентированных. –

0

Как сказал pguardiario, метод partition является наиболее прямым путем , Вы можете также использовать Set#divide:

require 'set' 
list = (1..10).to_a 
odd, even = Set.new(list).divide(&:odd?).to_a.map{|x| x.to_a} 
0

Вы можете попробовать ниже:

odd,even = (0..20).group_by(&:odd?).values 
p odd,even 

Выход:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]