This mostly just strikes me as a bad idea, the reason you'd initialize the accumulator with an empty collection is so that you can operate uniformly, i.e. normally you don't have special-case logic like if(t.isEmpty) ... else ...
I don't know your application, though, so let's suppose you really need to do this, that whatever you are doing in your ordinary operation requires a nonempty Collection which must first be initialized with a single-element Collection that contains the first encountered element but then must operate differently thereafter.
The first thing to point out is that your existing approach may not be terrible. You are working to eliminate one object allocation, which is unlikely to be a performance bottleneck. "Premature optimization is the root of all evil", sez Donald Knuth.
A second thing to point out is that you oughtn't in general create an empty Collection in scala as collection[T]()
. If collection
stands in for the name of some collection class or trait, there is probably a method like collection.empty[T]
that provides an empty instance without a new allocation each time. So the simplest optimization is just...
collection1.foldLeft(collection.empty[T])({
{ case(t,otherstuff) =>
if(t.isEmpty) new T(otherstuff) else ...}
})
If collection
stands in for some custom immutable collection class whose companion does not offer an empty method, define one, in the collection's companion object if you can, elsewhere if you can't.
private val emptyCollection = collection[Nothing]()
def empty[T] : collection = emptyCollection.asInstanceOf[T]
If you are sure that the collection you fold over will contain at least one element, you could avoid the empty check every time with:
val pair = collection1.splitAt(1)
pair._2.foldLeft(pair._1){(col, next) =>
...
}
Where ...
is the else
case of your original empty check, no more if
necessary. To make that general, wrap it in a test
if ( !collection1.isEmpty ) {
val pair = collection1.splitAt(1)
pair._2.foldLeft(pair._1){(col, next) =>
...
}
} else {
appropriateDefaultResult
}