2016-01-13 5 views
0

Я программирую в Ruby.Альтернативное форматирование строк с несколькими строками в каждом наборе

Учитывая, что у меня есть следующий 2D массив:

list = [ 
    ["T1", "Cat 1"], 
    ["T2", "Cat 2"], 
    ["T3", "Cat 3"], 
    ["T4", "Cat 4"], 
    ["T5", "Cat 1"], 
    ["T6", "Cat 2"], 
    ["T7", "Cat 3"], 
    ["T8", "Cat 4"], 
    ["T9", "Cat 1"], 
    ["T10", "Cat 2"], 
    ["T11", "Cat 3"], 
    ["T12", "Cat 4"], 
] 

У меня также есть список категорий:

cat = ["Cat 1", "Cat 2", "Cat 3", "Cat 4"] 
cat_count = cat.count 

У меня также есть метод bold, который форматирует текст полужирный, простота здесь. Я собираюсь использовать следующий метод:

def bold(text) 
    'b_' << text 
end 

Я бы хотел ke для форматирования каждого набора категорий чередующимся образом. Таким образом, первый набор будет жирным шрифтом, а затем второй набор не, третий набор жирного шрифта, четвертый набор не т.д.

В этом случае я хотел бы получить следующий форматированный вывод: T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12

Я ожидаю, что следующий рубиновый вывод:

["b_T1", "Cat 1"] 
["b_T2", "Cat 2"] 
["b_T3", "Cat 3"] 
["b_T4", "Cat 4"] 
["T5", "Cat 1"] 
["T6", "Cat 2"] 
["T7", "Cat 3"] 
["T8", "Cat 4"] 
["b_T9", "Cat 1"] 
["b_T10", "Cat 2"] 
["b_T11", "Cat 3"] 
["b_T12", "Cat 4"] 

У меня есть следующий код на данный момент, который совсем не выглядит рубистом. Пожалуйста, помогите мне улучшить этот код.

cat_increment = 0 
switch = 1 

list.map do |l| 
    cat_increment+=1 
    entry = switch ? [bold(l.first), l.second] : l 
    if cat_increment == cat_count 
    switch = switch ? nil : 1 
    cat_increment = 0 
    end 
    entry 
end 
+1

Не ясно как задействован массив 'cat'. Исправлен ли цикл в «списке»? Если это так, то важна только длина цикла. Я не понимаю, почему у вас есть этот конкретный массив 'cat'. Или, это там больше с «кошкой»? – sawa

+0

Цикл в списке фиксирован. – Steve

+0

Автомобильный массив дает длину категорий, которые нужно искать, так что мне не нужно делать group_by – Steve

ответ

3

Вы можете использовать with_index, array decomposition и математику:

list.map.with_index do |(title, category), index| 
    if index % (2 * cat_count) < cat_count 
    [bold(title), category] 
    else 
    [title, category] 
    end 
end 
+1

Комментарий пилы к исходному вопросу справедлив. Я предполагаю, что вы используете 'cat' для построения' list'. Если это так, могут быть даже лучшие способы добраться туда, где вы хотите. Однако я оставлю это другим. – Raffael

+0

Я не использую cat для создания списка. Оба исходят из других служб, которыми я не владею. – Steve

+0

Кроме того, список является грубым упрощением большого 2D-массива – Steve

1
enum = [*["b_"]*cat.size, *[""]*cat.size].cycle 
    #=> #<Enumerator: ["b_", "b_", "b_", "b_", "", "", "", ""]:cycle> 
list.map { |t,c| [enum.next+t, c] } 
    #=> [["b_T1", "Cat 1"], ["b_T2", "Cat 2"], ["b_T3", "Cat 3"], ["b_T4", "Cat 4"], 
    # ["T5", "Cat 1"], ["T6", "Cat 2"], ["T7", "Cat 3"], ["T8", "Cat 4"], 
    # ["b_T9", "Cat 1"], ["b_T10", "Cat 2"], ["b_T11", "Cat 3"], ["b_T12", "Cat 4"]] 

Array#cycle используется для преобразования массива ["b_", "b_", "b_", "b_", "", "", "", ""] в бесконечно повторяющемся переписчик.

Это тогда просто вопрос отображения каждого элемента list на новое значение, в котором строка «Т» предваряется к следующему элементу enum ("b_" или "").

Я решил использовать этот перечислитель, чтобы добавить «T» префиксы, которые чередуются с каждой группой cat.size элементов, но более обычным способом является использование индексов:

list.map.with_index { |(t,c),i| [(i/4).even? ? "b_"+t : "t", c] } 
    #=> [["b_T1", "Cat 1"], ["b_T2", "Cat 2"], ["b_T3", "Cat 3"], ["b_T4", "Cat 4"], 
    # ["T5", "Cat 1"], ["T6", "Cat 2"], ["T7", "Cat 3"], ["T8", "Cat 4"], 
    # ["b_T9", "Cat 1"], ["b_T10", "Cat 2"], ["b_T11", "Cat 3"], ["b_T12", "Cat 4"]] 

С Рубином 2.3.1 вы сможете написать:

list.each_with_index { |(t,_),i| print "#{ (i/4).even? ? t.boldify : t } " } 

T1T2T3T4 T5 T6 T7 T8 T9T10T11T12