Непоследовательное поведение для xs.sliding(n), если n меньше размера?
Согласно scaladoc, slide () возвращает...
"Итератор, создающий итерируемые коллекции размера size
, за исключением того, что последний и единственный элемент будет усечен, если будет меньше элементов, чем size
".
Для меня, интуитивно понятно, скольжение (n) вернет скользящее окно из n элементов, если доступно. В текущей реализации мне нужно выполнить дополнительную проверку, чтобы убедиться, что я не получаю список из 1 или 2 элементов.
scala> val xs = List(1, 2)
xs: List[Int] = List(1, 2)
scala> xs.sliding(3).toList
res2: List[List[Int]] = List(List(1, 2))
Я ожидал здесь пустой список вместо этого. Почему slide () реализован именно так?
3 ответа
Это была ошибка, но она не была исправлена с 2.9. Все время от времени допускают ошибки проектирования, и как только кто-то попадает в библиотеку, ее нетривиальная задача удалить.
Обходной путь: добавьте фильтр.
xs.sliding(3).filter(_.size==3).toList
Вы можете "обойти" это с помощью GroupedIterator#withPartial
модификатор.
scala> val xs = List(1, 2)
xs: List[Int] = List(1, 2)
scala> xs.iterator.sliding(3).withPartial(false).toList
res7: List[Seq[Int]] = List()
(Я не знаю, почему вы должны сказать xs.iterator
но xs.sliding(3).withPartial(false)
не работает, потому что вы получаете Iterator
вместо GroupedIterator
,
РЕДАКТИРОВАТЬ:
Проверьте ответ Рекса (который является правильным). Я оставляю это только потому, что (как сказал Рекс в комментариях) это была оригинальная (неправильная) идея, лежащая в основе этого решения.
Я не знаю, почему вы ожидаете пустой список там, возвращение полного списка кажется лучшим результатом, рассмотрим этот пример:
def slidingWindowsThing(windows : List[List[Int]]) { // do your thing
Для этих методов вы, вероятно, хотите, чтобы все эти вызовы работали:
slidingWindowsThing((1 to 10).sliding(3))
slidingWindowsThing((1 to 3).sliding(3))
slidingWindowsThing((1 to 1).sliding(3))
Вот почему метод по умолчанию имеет список размеров list.length
вместо Nil
(пустой список).