Выбор между использованием 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.

Другие вопросы по тегам