2015-10-12 2 views
-6

У меня есть следующий массив:Как заказать массив в Ruby,

a = [1, 1, 1, 1, 1, 1, 1, 2, 2, 3] 

Я хочу, чтобы изменить порядок его последовательных возрастающих последовательностей. Например:

  1. В начале, у меня есть семь 1 с, два 2 с, и один 3. В результате я начинаю вывод с [1, 2, 3].
  2. Теперь у меня есть шесть 1 и один 2, поэтому я затем добавляю [1, 2] в выходной массив.
  3. На данный момент у меня есть пять 1 s и никакие другие номера, поэтому я добавлю последовательность [1] в выходной массив пять раз.

Для примера входных данных, я в конечном итоге следующий вывод:

a = [1, 2, 3, 1, 2, 1, 1, 1, 1, 1] 

Можете ли вы помочь мне, пожалуйста?

+0

@josilber Возможно, это «создать co последовательные возрастающие последовательности, насколько это возможно, с тем, что осталось ». Но для этого требуется, чтобы исходный массив имел некоторое свойство, о котором OP не упоминает, поэтому не имеет значения, что вопрос не ясен. – sawa

+0

Вот один из способов: 'a = [1, 3, 1, 2, 1, 1, 1, 1, 2, 1]; b = a.sort.chunk (&: self) .map (&: last) # => [[1, 1, 1, 1, 1, 1, 1], [2, 2], [3]]; b.first.size.times.flat_map {b.map (&: shift) .compact} # => [1, 2, 3, 1, 2, 1, 1, 1, 1, 1] '. –

+2

Хорошее редактирование! Еще одно: вы должны указать, должны ли элементы быть заказаны (как они есть в exaample). Для них, чтобы быть заказанным, просто включает в себя первоначальный вид, но вы должны сделать это ясно. Если они не обязательно упорядочены, измените массив экземпляров на один, это не упорядочено. Читатели: проголосуйте за повторное открытие. –

ответ

1

Похоже, что вы пытаетесь сделать это:

  1. Группа массив по значению:

    [1, 1, 1, 1, 1, 1, 1] 
    [2, 2] 
    [3] 
    
  2. Затем идут от верха до низа и слева направо, пропуская через отсутствующие записи.

Транслитерация процесса в Ruby может выглядеть примерно так.

Сначала создайте свои группы; Я не уверен, если массив будет всегда в таком порядке, так что есть некоторые дополнительные упорядочено здесь, чтобы избежать при условии, как исходный массив упорядочен или как group_by пересечет массив:

first, *rest = a.group_by { |e| e }.values.sort_by(&:first) 

Это даст вам это :

first = [ 1, 1, 1, 1, 1, 1, 1 ] 
rest = [ [2, 2], [3] ] 

Затем вы можете использовать zip чередовать сгруппированных массивы:

first.zip(*rest) 
# [[1, 2, 3], [1, 2, nil], [1, nil, nil], [1, nil, nil], [1, nil, nil], [1, nil, nil], [1, nil, nil]] 

и бросить в flatten вызовов, ну, сглаживать внутренние массивы и compact выбросить все nil s, что zip добавил:

first.zip(*rest).flatten.compact 
# [1, 2, 3, 1, 2, 1, 1, 1, 1, 1] 

Конечно, это предполагает, что first будет самым длинным из сгруппированных массивов (благодаря John La Rooy для отмечая этот недосмотр).Если вы не знаете, что (или не хотят считать его), то вы могли бы ноль-подушечка first перед вызовом zip:

max = [ first.length, *rest.map(&:length) ].max 
first += [ nil ] * max if(first.length != max) 

Вы также должны убедиться, что a не пуст или вы в конечном с first быть nil:

def whatever_this_is_called(a) 
    return [ ] if(a.nil? || a.empty?) 

    first, *rest = a.group_by { |e| e }.values.sort_by(&:first) 
    max = [ first.length, *rest.map(&:length) ].max 
    first += [ nil ] * max if(first.length != max) 
    first.zip(*rest).flatten.compact 
end 
+2

Это нормально, считая, что 'first' является самым длинным списком. –

+0

@JohnLaRooy: Спасибо, что указали это. Проверка того, что '! A.пути? 'Также стоит избегать' first.nil? '. –

1

Как я предложил в моем комментарии выше, вы можете сделать это:

def doit(arr) 
    a = arr.sort.chunk(&:itself).map(&:last) 
    a.map(&:size).max.times.flat_map { a.map(&:shift).compact } 
end 

doit [1, 1, 1, 1, 1, 1, 1, 2, 2, 3] 
    #=> [1, 2, 3, 1, 2, 1, 1, 1, 1, 1] 
doit [1, 3, 1, 2, 1, 1, 1, 1, 2, 1] 
    #=> [1, 2, 3, 1, 2, 1, 1, 1, 1, 1] 
doit [2, 1, 3, 2, 1, 2, 2, 2, 2, 2] 
    #=> [1, 2, 3, 1, 2, 2, 2, 2, 2, 2] 

Предположим:

arr = [2, 1, 3, 2, 1, 2, 2, 2, 2, 2] 

Затем шаги заключаются в следующем:

b = arr.sort 
    #=> [1, 1, 2, 2, 2, 2, 2, 2, 2, 3] 
c = b.chunk(&:itself) 
    #=> #<Enumerator: #<Enumerator::Generator:0x007fbe918969b0>:each> 

Мы можем преобразовать нумератор c в массив, чтобы увидеть его элементы:

c.to_a 
    #=> [[1, [1, 1]], [2, [2, 2, 2, 2, 2, 2, 2]], [3, [3]]] 

Тогда:

a = c.map(&:last) 
    #=> [[1, 1], [2, 2, 2, 2, 2, 2, 2], [3]] 
d = a.map(&:size) 
    #=> [2, 7, 1] 
e = d.max 
    #=> 7 
f = e.times 
    #=> #<Enumerator: 7:times> 
f.to_a 
    #=> [0, 1, 2, 3, 4, 5, 6] 
f.flat_map { a.map(&:shift).compact } 
    #=> [1, 2, 3, 1, 2, 2, 2, 2, 2, 2] 
Смежные вопросы