2013-07-31 2 views
11

Как удалить некоторые элементы из массива и выбрать их?Удалить из массива и вернуть удаленные элементы в Ruby

Например:

class Foo 
    def initialize 
    @a = [1,2,3,4,5,6,7,8,9] 
    end 

    def get_a 
    return @a 
    end 
end 

foo = Foo.new 
b = foo.get_a.sth{ |e| e < 4 } 
p b # => [1,2,3] 
p foo.get_a # => [4,5,6,7,8,9,10] 

Что я могу использовать вместо foo.get_a.sth?

+0

Ваша переменная экземпляра '@ a' в классе' Foo' ничего не делает. Вы должны удалить его. – sawa

+0

Вопрос абстрагируется, и деталь удаляется. вы можете предположить, что строка '@a = [1,2,3,4,5,6,7,8,9]' является результатом некоторого процесса. – NewMrd

+0

Прошу прощения !! Я привык к форме java !!! : p – NewMrd

ответ

22

Если вам не нужно, чтобы сохранить идентификатор объекта a:

a = [1,2,3,4,5,6,7,8,9,10] 
b, a = a.partition{|e| e < 4} 
b # => [1, 2, 3] 
a # => [4, 5, 6, 7, 8, 9, 10] 

Если вам нужно сохранить идентификатор объекта a, а затем использовать временный массив c:

a = [1,2,3,4,5,6,7,8,9,10] 
b, c = a.partition{|e| e < 4} 
a.replace(c) 
+1

хороший ответ, но я не могу изменить 'a'. 'a' является результатом функции' some_object.get_some_array' – NewMrd

+0

@NewMrd Почему вы не можете изменить его? Переменная - это переменная, поэтому вы всегда можете назначить ее результатом этого вызова, тогда этот шаблон работает нормально. – tadman

+4

Можете ли вы не просто использовать 'a.select {| e | e <4} 'в этом случае? Это вернет элементы, которые проходят тест. –

0
a = [1, 2, 3, 4] 
a.dup - (a.delete_if(&:even?)) 
#=> [2, 4] 

a 
#=> [1, 3] 

a = [1, 2, 3, 4] 
b = a.dup - (a.delete_if { |e| e < 4 }) 
a 
#=> [4] 
b 
#=> [1, 2, 3] 

Редактировать: Похоже, вы сразу после #select ...

a = [1, 2, 3, 4] 
a.select { |e| e < 3 } 
#=> [1, 2] 
+0

Если есть повторяющиеся элементы, тогда блок будет возвращать то же самое для обоих из них, чтобы это не было проблемой! –

+0

Можете ли вы привести пример? –

+1

Возможно, я ошибся. Сожалею. – sawa

1

Если вы удаляете только один элемент, это не требует дублирования массива и т.д.:

array = [{ id: 1 }, { id: 2 }, {id: 3 }] 
array.delete_at(array.find_index { |element| element[:id] == 1 }) 
#=> {:id=>1} 
+1

Это идеальное решение для моего приложения для аналогичных потребностей. – Jay

+0

это не удастся, если find_index возвращает nil – mountriv99

0

Я до сих пор не верю, рубин не есть что-то для этого в своих библиотеках по умолчанию. Для этого должен быть эквивалентен метод #drop. Разумеется, есть драгоценный камень, который добавит функциональность в класс массива. Но кому нужен драгоценные камни, когда вы можете просто выйти свои собственные сценарии:

#in initializer somewhere 
class Array 
    def exclude(obj) 
    x = self 
    x.delete(obj) 
    x 
    end 
end 

я могу подать запрос на тянущий на GitHub проект рубинового для этого метода. Этот супермен-патч работает очень хорошо.