2012-04-09 2 views
1

Мне нужно сгруппировать числа, которые находятся в числовом порядке из массива.Номера групп по номеру в рубине

(с использованием рубин 1.9.2, рельсы 3.2)

Example1: 
[1,2,4,5,6] 

Example2: 
[1,3,4,6,7] 

Example3: 
[1,2,3,5,6] 

Example4: 
[1,2,4,5,7] 

После группировки

Example1: 
[[1,2],[4,5,6]] 

Example2: 
[[1],[3,4],[6,7]] 

Example3: 
[[1,2,3],[5,6]] 

Example4: 
[[1,2],[4,5],[7]] 

Вы получаете идею. (То, что я на самом деле делаю, это группирование дней, не относящихся к делу)

Заранее спасибо!

+1

Вы хотите сгруппировать * * последовательные числа вместе, не так ли? –

ответ

3

Я не уверен, что бы вы назвали этой операцией, но это своего рода метод группировки, основанный на обработке последнего элемента. Что-то вроде:

def groupulate(list) 
    list.inject([ ]) do |result, n| 
    if (result[-1] and result[-1][-1] == n - 1) 
     result[-1] << n 
    else 
     result << [ n ] 
    end 

    result 
    end 
end 

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

+0

Это лучший ответ :) –

+0

Отлично, отмечая это как правильный ответ, хотя ответ @ tjdett тот же. Спасибо. –

+3

['each_with_object'] (http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-each_with_object), вероятно, имеет здесь больше смысла, чем' inject', поскольку вы просто передаете один и тот же объект между итерациями. –

1
a = [1,2,4,5,7] 
out = [] 
a.each_index do |i| 
    if out.last and out.last.last == a[i]-1 
    out.last << a[i] 
    else 
    out << [a[i]] 
    end 
end 

puts out.inspect 
+0

Полностью работает, спасибо. –

+0

Думаю, я пойду с ответом @ tadman :) –

+0

Вы должны! :) Забавная проблема! –

2

Идеальная проблема использования inject (ака reduce) с:

def group_consecutive(arr) 
    arr.inject([[]]) do |memo, num| 
    if memo.last.count == 0 or memo.last.last == num - 1 
     memo.last << num 
    else 
     memo << [ num ] 
    end 
    memo 
    end 
end 

Посмотреть работать здесь: http://rubyfiddle.com/riddles/0d0a5

+1

Как отмечалось в другом ответе, используя 'injection', [' each_with_object'] (http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-each_with_object), вероятно, имеет смысл здесь, чем 'inject', поскольку вы просто передаете один и тот же объект между итерациями. –

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