У меня есть массив похожих объектов с атрибутом a
, который может иметь значения b
или c
. Массив можно рассматривать как набор строк, где каждая пара элементов массива представляет одну строку. Я только что перечислил значение атрибута a
для простоты, Примера:Итерация и мутация массива Ruby
array = [c, b, b, c, c, c, b]
# array[0], array[1] is one row (c, b)
# array[2], array[3] is another (b, c)
# ...
Там не может быть строки просто (b, b)
, и если это так, то один из b
значений следует поменять местами для ближайший c
значение в массиве. Если значений c
больше, то массив действителен до тех пор, пока значения b
не останутся в конце массива.
final строка массива может состоять только из одна значение, i. е. (b,).
Пример:
array = [b, c, b, b, c, b, b, b, c, b, b, c, c]
# becomes
array = [b, c, b, c, b, b, b, b, c, b, b, c, c]
array = [b, c, b, c, b, c, b, b, b, b, b, c, c]
array = [b, c, b, c, b, c, b, c, b, b, b, b, c]
array = [b, c, b, c, b, c, b, c, b, c, b, b, b]
# rows: (b, c), (b, c), (b, c), (b, c), (b, c), (b, b,), (b,)
Это решение, которое я придумал, что я не очень нравится (потому что это очень важно и многословным)
while true do
cand = nil
array.each_slice(2) do |item, nxt|
return if nxt.nil?
# pseudo-code: assume b? returns true for a == b
next unless item.b? && nxt.b?
cand = nxt
break
end
swap_cand = array.slice(array.index(cand), array.length).reject{ |item| item.popular? }.first
return if swap_cand.nil?
old_index, new_index = array.index(cand), array.index(swap_cand)
array[old_index], array[new_index] = array[new_index], array[old_index]
end
Проблема я продолжал работать в заключалось в том, что я не мог мутировать массив во время итерации по нему, что потребовало двух циклов.
Редактировать Очистить некоторые высказывания о перерывах в предложениях от @ 7stud.
'возвращение сделано = верно, если nxt.nil?' А? Вы знаете, что такое LocalJumpError? Если код, который вы опубликовали, действительно находится внутри def, то что делает сделанная установка = true для вас? Когда вы возвращаетесь из def, больше нет цикла - больше ничего. – 7stud
Я предположил, что это просто установит переменную 'done' и впоследствии выйдет из цикла' each_slice'. Это действительно внутри определения функции, и, как указано циклом 'until', этот внешний цикл завершается, когда' done' является 'true'. – nicohvi
** Проблема, с которой я столкнулась, заключалась в том, что я не мог мутировать массив, итерации по ней **. 'results = []; temp = []; arr.each do | obj | результаты << obj #or temp << obj. Используйте столько массивов, сколько вам нужно, и перемешайте вещи между ними в каждом цикле. – 7stud