Удалить из массива и вернуть удаленные элементы в 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?

Ответ 1

Если вам не нужно сохранять идентификатор объекта 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)

Ответ 2

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

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

Ответ 3

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]

Ответ 4

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

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

Я могу отправить запрос на перенос в проект ruby ​​github для этого метода. Этот супермен-патч очень хорошо работает до сих пор.