2015-01-05 2 views

ответ

9

Наиболее лаконичная версия:

val isAllSizeOne = foo.forall(_.size == 1) 

Другим вариант, который может быть быстрее, но менее лаконичный:

val isAllSizeOne = foo.forall(_.lengthCompare(1) == 0) 
+3

В частности, 'lengthCompare' быстро подходит для последовательностей, которые не знают своего собственного размера, например' List', так как он может выпустить раннее, а не считать все, если находит более одного элемента. Для последовательностей, которые знают свою собственную длину, для этого требуется дополнительная логика, которая надеется, что JVM в конечном итоге оптимизируется. (Обычно это по моему опыту, по крайней мере, в сильно используемых кодах, которые мне очень нравятся.) –

9

Метод forall предназначен для того, чтобы делать именно то, что вы просите.

foo.forall(_.size == 1) 

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

4

Для очень больших коллекций, стоит рассмотреть также запараллеленную версию с помощью par, для например,

foo.par.forall(_.size == 1) 
1
операция

Размер требует перебора всех элементов в последовательности, другой альтернативы может быть:

foo.forall(l => l.nonEmpty && l.tail.isEmpty) 

Хотя, учитывая размер последовательности мал, он не имеет большого значения.

+1

Плохая идея! 'tail', для большинства' Seq's (список сохранения, который, по общему признанию, является реализацией по умолчанию), создаст новую коллекцию! Если он неизменен, это может быть не очень дорого, но это, безусловно, будет дороже, чем подсчет элементов. Вы должны делать это только в том случае, если вы действительно уверены, что ваша операция 'tail' является недорогой (например, вы' LinearSeqLike'). –

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