2015-11-10 3 views
2

В Ruby, я хочу pop элемент (самый маленький) выходной массив и push тот же элемент на новый массив. Мне это нужно, чтобы быть такой же элемент, который получает push «д, потому что я хочу сделать это рекурсивно без этого происходит:Ruby: `pop`ing одного массива и` push`ing на другой

a = [1,4,2,3,5,7,8,6] 
b = [] 
b.push(a.min) #=> b = [1] 
b.push(a.min) #=> b = [1,1] 
b.push(a.min) #=> b = [1,1,1] 

Вместо

b.push(a.min) #=> b = [1] 
b.push(a.min) #=> b = [1,2] 
b.push(a.min) #=> b = [1,2,3] 

EDIT:

следовало бы упомянуть , я стараюсь не использовать sort, спасибо!

ответ

3

Вопрос запрошен рекурсивным методом. Ни один из других ответов не является рекурсивным.

Вот рекурсивное решение:

class Array 
    def recursive_pop 
    any? ? [delete(min)] + recursive_pop : [] 
    end 
end 

irb(main):082:0> original_array = [1,2,3] 
    => [1, 2, 3] 
irb(main):083:0> new_array = original_array.recursive_pop 
    => [1, 2, 3] 
irb(main):084:0> new_array 
    => [1, 2, 3] 
irb(main):085:0> original_array 
    => [] 

В соответствии с просьбой, метод удаляет минимальный элемент в исходном массиве один за другим, и добавляет элемент в новый массив.

+0

Майк, вы указали, что OP хочет удалить значения из исходного массива, и я не сделал этого в своем ответе. Я уверен, что вы правы и благодарны за это. Я удалил свой ответ, но могу исправить его и восстановить –

+1

@CarySwoveland, что понятно. Вопрос довольно плохо сформулирован, поэтому он выглядит двусмысленным. –

+0

@ Майк Ха, не так ли? Я думал, что это довольно ясно. Как я могу улучшить его? – Adzz

1

Если я правильно понимаю вас, вы можете сделать начальный массив sort, а затем использовать метод shift для извлечения первого элемента.

a = [1,4,2,3,5,7,8,6].sort 
b = [] 
b.push(a.shift) #=> b = [1] 
b.push(a.shift) #=> b = [1,2] 
b.push(a.shift) #=> b = [1,2,3] 
+0

Это не рекурсивно. –

+0

было бы хорошо, но должно было сказать, что пытались конкретно не использовать сортировку. – Adzz

1

Если это строго численный номер, который вы ищете (или в алфавитном порядке), вы всегда можете просто использовать array.sort.

a = a.sort

становится

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

Тогда

b.push(a.shift)

1

С v.2.2 +, вы можете использовать Enumerable#min с аргументом:

def pop_n_push(arr, n) 
    arr.min(n).each { |e| arr.delete_at(arr.index(e)) }.to_a 
end 

arr = [7,8,1,4,2,3,5,2,6] 
new_arr = pop_n_push(arr, 4) 
    #=> [1, 2, 2, 3] 
arr 
    #=> [7, 8, 4, 5, 6] 

min возвращает нумератор, содержащий n наименьшие элементы arr. Каждый из этих элементов находится и удаляется с arr. (Повторяющиеся значения не являются проблемой.) Enumerator#each возвращает свой ресивер, перечислитель, который затем преобразуется в массив и возвращается методом. вместо того, чтобы можно было бы написать:

arr.min(n).to_a.each { |e| arr.delete_at(arr.index(e)) } 

Обратите внимание, что этот метод сохраняет порядок элементов в arr. Он также должен быть быстрее сортировки массива, когда n существенно меньше arr.size.

+1

Должна ли вторая строка быть 'arr' вместо' a' и 'n' вместо' 3'? –

+0

Вопрос о том, чтобы элемент был выбит, но вы сказали в своем ответе, что 'a' не изменилось. Появление этого слова означает, что 'a' должно измениться. –

+0

Спасибо, @ sagarpandya82.Я написал это на телефоне, на котором я не мог запустить Ruby v2.2, поэтому я не смог проверить, что я почти всегда делаю. Тем не менее, это довольно плохой надзор. Я исправил это и внес некоторые другие изменения. –

Смежные вопросы