Это распространенный сценарий, и я никогда не доволен решениями. У вас есть набор данных, в данном случае просто предположим, что строки из БД упорядочены по категориям.
Вы хотите создать буфер с подмножеством каждой категории, и при каждом изменении категории выполнить некоторую обработку, а затем очистить буфер. Предположим, что process () обернут в сложную логику, которую вы не хотите дублировать
У кого-нибудь есть лучшие настройки?
# category, city
data = [
[10, 'citya'],
[10, 'cityb'],
[11, 'citya'],
[11, 'cityb'],
[11, 'citya'],
[12, 'cityb'],
[12, 'cityg']
]
# do some heavy lifting in here
def process(buf) p buf; end
cur_cat = nil
cur_cat_buf = []
data.each do |r|
if r[0] != cur_cat
cur_cat = r[0]
process(cur_cat_buf) #<-- assume this is conditional, complex
cur_cat_buf.clear
end
cur_cat_buf << r[1]
end
process(cur_cat_buf) #<-- assume the conditional is duplicated...ack.
Это другая техника, и она просто ужасна. Грязно, ужасно! Всегда заглядывая в будущее, проверяя, является ли он нулевым или другим и т. Д. Тьфу ...
cur_cat = data[0][0] if data.length > 0
cur_cat_buf = []
data.each_with_index do |r, i|
cur_cat_buf << r[1]
# look ahead
if data[i+1] == nil or data[i+1][0] != cur_cat
cur_cat = data[i+1][0] if data[i+1] != nil
process(cur_cat_buf)
cur_cat_buf.clear
end
end
Это еще одна альтернатива. Конечно, лучше, чем предыдущий.
cur_cat = nil
cur_cat_buf = []
for i in 0..(data.length)
if (r = data[i]) == nil or r[0] != cur_cat
process(cur_cat_buf)
break unless r
cur_cat_buf.clear
cur_cat = r[0]
end
cur_cat_buf << r[1]
end
Я хочу чистое, элегантное решение. Должен быть лучший способ!