Скажем, у меня есть следующий массив, и я хотел бы избавиться от непрерывных дубликатов:
arr = [1,1,1,4,4,4,3,3,3,3,5,5,5,1,1,1]
Я хотел бы получить следующее:
=> [1,4,3,5,1]
Было бы здорово, если бы было что-то более простое и эффективное, чем мои решения (или их варианты):
(arr + [nil]).each_cons(2).collect { |i| i[0] != i[1] ? i[0] : nil }.compact
или
(arr + [nil]).each_cons(2).each_with_object([]) {
|i, memo| memo << i[0] unless i[0] == i[1]
}
EDIT: Похоже, что решение @ArupRakshit ниже очень просто. Я все еще ищу лучшую эффективность, чем мое решение.
EDIT:
Я буду тестировать ответы, когда они придут:
require 'fruity'
arr = 10000.times.collect { [rand(5)] * (rand(4) + 2) }.flatten
compare do
abdo { (arr + [nil]).each_cons(2).collect {
|i| i[0] != i[1] ? i[0] : nil }.compact
}
abdo2 {
(arr + [nil]).each_cons(2).each_with_object([]) {
|i, memo| memo << i[0] unless i[0] == i[1]
}
}
arup { arr.chunk(&:to_i).map(&:first) }
arupv2 { arr.join.squeeze.chars.map(&:to_i) }
agis {
i = 1
a = [arr.first]
while i < arr.size
a << arr[i] if arr[i] != arr[i-1]
i += 1
end
a
}
arupv3 { arr.each_with_object([]) { |el, a| a << el if a.last != el } }
end
Результаты тестов:
agis is faster than arupv3 by 39.99999999999999% ± 10.0%
arupv3 is faster than abdo2 by 1.9x ± 0.1
abdo2 is faster than abdo by 10.000000000000009% ± 10.0%
abdo is faster than arup by 30.000000000000004% ± 10.0%
arup is faster than arupv2 by 30.000000000000004% ± 10.0%
Если мы используем:
arr = 10000.times.collect { rand(4) + 1 } # less likelihood of repetition
Получаем:
agis is faster than arupv3 by 19.999999999999996% ± 10.0%
arupv3 is faster than abdo2 by 1.9x ± 0.1
abdo2 is similar to abdo
abdo is faster than arupv2 by 2.1x ± 0.1
arupv2 is similar to arup