Выбор между использованием foldleft() или Seq.newBuilder в Scala
У меня есть некоторый код, где мне нужно добавить элементы в последовательность, перебирая другую. Какой способ является "предпочтительным" или, вернее, лучшим способом сделать это в Scala и почему?
Способ 1:
val builder = Seq.newBuilder[String]
for(i <- iterator){
builder += i //Everytime I want to add a new element
}
Способ 2:
val stringSeq = iterator.foldLeft(Seq[String]()){
case (acc, i) => i +: acc
}
3 ответа
Я бы сказал, что путь 2 более идиоматичен и более функциональный, так как вы не создаете изменяемое состояние.
" Путь 1" кажется более обязательным, так как он напоминает for
как это используется в объектно-ориентированном программировании.
Однако в Scala есть как элементы ООП, так и элементы FP. Я думаю, вам следует использовать конструкцию, которая работает лучше для вас, например, из-за соображений производительности (однако я не думаю, что ваш пример имеет место, как добавление к главе Seq
должно быть быстро).
PS. ваш генератор должен быть <-
не <
и это foldLeft
(заглавная L)
Почему бы не использовать оба, и быть функциональным и эффективным?
iterator.foldLeft(Seq.newBuilder[String])(_ += _).result
Обратите внимание, что поведение этого кода немного отличается от поведения вашего второго решения: ваше решение изменяет порядок итератора, мое сохраняет его. Я не знаю, что желательно.
Кроме того, на тот случай, если вам это не пришло в голову (извините, если я вас понимаю), по какой-то конкретной причине вы не используете iterator.toSeq
?
E сть ++:
метод в Seq
так что вы можете просто сделать seq ++: iterator
И не беспокойтесь о производительности, это базовый API, предоставляемый Scala, и мы должны доверять ему.
На самом деле текущая реализация похожа на ваш путь 1.