keerthi
keerthi

Reputation: 23

List[List[String]] in Scala

We have a list of strings and i grouping them by below program. input: val k = List("a", "a", "a", "a", "b", "c", "c", "a", "a", "d", "e", "e", "e", "e")

output: *List(List(a, a, a, a), List(b), List(c, c), List(a, a), List(d), List(e, e, e, e))*

Program:

  def pack(ls:List[String]):List[List[String]]={

    val (a,next) = ls span {_ == ls.head}

    if ((next) == Nil) List(a)
    else a :: pack(next)

  }          

However when i do a List cons operators, i get the output as mentioned below.

Input:

val a =List("a", "a", "a", "a")        
val b = List ("b")                     
val c = List ("c", "c" )               
val a1 = List("a", "a")                
val d = List("d")                      
val e = List( "e", "e", "e", "e")      

*List(a::b::c::a1::d::e)*                

output:

*List(List(List(a, a, a, a), List(b), List(c, c), List(a, a), List(d), e, e, e, e))*

Is there any way i can the output as below in a single command in scala?

*List(List(a, a, a, a), List(b), List(c, c), List(a, a), List(d), List(e, e, e, e))* 

Upvotes: 0

Views: 974

Answers (3)

DK_
DK_

Reputation: 2658

Yes. If you really want to use that syntax:

List(a::b::c::a1::d::e::Nil: _*)

You need the : _* at the end because otherwise you are passing a single element (of type List) to List.apply() and it is not interpreting it as a sequence, which is why you get List[List[List]] instead of the desired List[List].

Upvotes: 1

Johny T Koshy
Johny T Koshy

Reputation: 3887

If you are planning to achieve the end result using ::, adding a Nil at the end to the cons operation could yield the desired result.

a::b::c::a1::d::e::Nil

or you could wrap the last element in a List as @Tzach Zohar has mentioned.

a::b::c::a1::d::List(e)

Otherwise use

List(a,b,c,a1,d,e)

Upvotes: 1

Tzach Zohar
Tzach Zohar

Reputation: 37822

scala> a::b::c::a1::d::List(e)
res0: List[List[String]] = List(List(a, a, a, a), List(b), List(c, c), List(a, a), List(d), List(e, e, e, e))

The cons operator prepends an item to a list - so construct a List around the last one if you want to then prepend all the other items one by one.

The easiest way to think about this is noticing the types:

  • To construct a List[List[String]], the cons operator expects to operate on an a List[String] on the left and a List[List[String]] on the right, to produce a new List[List[String]]: on the left should be an item in the resulting list, and on the right - a list with the same type as the expected result
  • When you write d::e, you're doing List[String] :: List[String], which already means you're not going to produce a List[List[String]] - so the right-hand side must be "wrapped" with a list to get the types right: d::List(e)
  • Prepending the other items follows the same rule - prepending List[String]s to a List[List[String]]
  • Once this is done - you get the expected result, without having to wrap the entire result with another list

Upvotes: 1

Related Questions