Reputation: 35
I have the following function which returns a list of 8 elements or list:
def orderCost(orderItems: List[Double]) = {
if (orderItems.length <= 8) orderItems else orderItems.grouped(8).toList
}
So my question is that why my function is returning List[Any] instead of List[Double] or List[List[Double]]. Is there a bug 2.11.8 which i'm using.
orderItems can be one of the below:
orderItems: List[Double] = List(4.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99)
or
orderItems: List[Double] = List(4.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 4.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99)
I want to a list of eight elements if order item length is 8 or create a multiple list from order item, where each sub list contains 8 elements max
Thanks
Upvotes: 0
Views: 80
Reputation: 27356
The problem is that the only type that is compatible with both List[Double]
and List[List[Double]]
is List[Any]
, so that is the result type of the function. There are no union types (until 3.0) so you can't return List[Double] | List[List[Double]]
.
You can unpick the current return value with a match
statement (but beware type erasure). Or you could return Either[List[Double], List[List[Double]]
like this:
def orderCost(orderItems: List[Double]) = {
if (orderItems.length <= 8) Left(orderItems) else Right(orderItems.grouped(8).toList)
}
orderCost(myItems) match {
case Left(ld) => // Handle List[Double]
case Right(lld) => // Handle List[List[Double]]
}
Upvotes: 1
Reputation: 14825
Just change the return of the function. grouped
with take care of all cases.
def orderCost(orderItems: List[Double]): List[List[Double]] =
orderItems.grouped(8).toList
scala> val l = (1 to 10)
l: scala.collection.immutable.Range.Inclusive = Range 1 to 10
scala> l.grouped(8).toList
res0: List[scala.collection.immutable.IndexedSeq[Int]] = List(Vector(1, 2, 3, 4, 5, 6, 7, 8), Vector(9, 10))
scala> val l = (1 to 4)
l: scala.collection.immutable.Range.Inclusive = Range 1 to 4
scala> l.grouped(8).toList
res1: List[scala.collection.immutable.IndexedSeq[Int]] = List(Vector(1, 2, 3, 4))
So, function looks like
scala> def orderCost(orderItems: List[Double]): List[List[Double]] = orderItems.grouped(8).toList
orderCost: (orderItems: List[Double])List[List[Double]]
scala> orderCost(List(1, 2, 3, 4))
res2: List[List[Double]] = List(List(1.0, 2.0, 3.0, 4.0))
scala> orderCost((1 to 20).toList.map(_.toDouble))
res4: List[List[Double]] = List(List(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0), List(9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0), List(17.0, 18.0, 19.0, 20.0))
Upvotes: 1
Reputation: 1892
You need not to check length, You can do directly like this
def orderCost(orderItems: List[Double]) = {
orderItems.grouped(8).toList
}
Sample Input 1:
val orderItems: List[Double] = List(4.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99)
Sample Output 1:
List(List(4.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99), List(8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99, 8.99), List(8.99, 8.99, 8.99, 8.99))
Sample Input 2:
val orderItems1: List[Double] = List(1,2,3,4,5.8)
Sample Output 2:
List(List(1.0, 2.0, 3.0, 4.0, 5.8))
Upvotes: 1