2014-12-22 3 views
0

Поэтому, учитывая, что у меня есть этот массив диапазонов:Сравнение элементов внутри массива диапазонов

[ 
    [0] Mon, 29 Dec 2014 07:30:00 PST -08:00..Mon, 29 Dec 2014 10:59:59 PST -08:00, 
    [1] Mon, 29 Dec 2014 12:30:01 PST -08:00..Mon, 29 Dec 2014 15:00:00 PST -08:00, 
    [2] Mon, 29 Dec 2014 07:30:00 PST -08:00..Mon, 29 Dec 2014 08:59:59 PST -08:00, 
    [3] Mon, 29 Dec 2014 10:30:01 PST -08:00..Mon, 29 Dec 2014 15:00:00 PST -08:00 
] 

Как сравнить диапазоны, которые имеют одинаковое минимальное значение, и удалить этот элемент, если максимальное значение больше, чем другие ?

+0

Существует несколько подходов, которые вы можете использовать. Один из них - 'group_by' начало диапазона, а затем для каждой группы сохраняют диапазон, конечное значение которого наименьшее. Другим является 'sort_by'' [r.first, -r.last] ', а затем объединить эти значения в изначально пустой хеш. –

+0

Я решил дать ответ, который реализовал два подхода, которые я предложил выше. –

ответ

1

двух способов, где a является массивом диапазонов :

# 1

a.each_with_object({}) { |r,h| h.update({ r.first=>r }) { |_,ov,nv| 
    [ov,nv].min_by(&:last) } }.values 

# 2

a.group_by(&:first).values.map { |r| r.min_by(&:last) } 
+0

пошел с решением №2. работает хорошо. благодаря – yretuta

1

Следует признать, что это будет медленно:

your_array.group_by do |range| 
    range.min 
end.each do |min_value, ranges| 
    least_max = ranges.map(&:max).min 
    ranges.delete_if{ |range| range.max != least_max } 
end.values 

Следующими может быть быстрее, а также удалят вещи из исходного массива:

min_maxes = {} 

your_array.each do |range| 
    min = range.min 
    max = range.max 

    if min_maxes[min].nil? || (min_maxes[min] > max) 
    min_maxes[min] = max 
    end 
end 

your_array.delete_if do |range| 
    min_maxes[range.min] < range.max 
end 
0

Если структура данных MultiMap мы можем обрабатывать этот сценарий легко. Это реализация хэширования с использованием двоичного дерева, а элементы упорядочены в ключах. И он позволяет дублировать ключи. Он есть на C++, не уверен, что в Ruby есть что-то подобное. Поскольку вопрос с меткой «структура данных», надеюсь, мой ответ распространил некоторые огни.

Для вашего случая вы можете рассматривать нижний диапазон как ключ и верхний диапазон как значение. Если в нижнем диапазоне есть столкновение, вы можете легко идентифицировать это и сравнить значения столкновений записей и удалить их, если это необходимо.

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