2

Good afternoon! I'm using Scala and I want to match first three element of a list and the last one, no matter how much of them are in the list.

val myList:List[List[Int]] = List(List(3,1,2,3,4),List(23,45,6,7,2),List(3,3,2,1,5,34,43,2),List(8,5,3,34,4,5,3,2),List(3,2,45,56))

def parse(lists: List[Int]): List[Int] = lists.toArray match{
  case Array(item, site, buyer, _*, date) => List(item, site, buyer, date)}

myList.map(parse _)

But I get : error: bad use of _* (a sequence pattern must be the last pattern) I understand why I get it, but how can I avoid?

My use case is that I'm reading from hdfs, and every file has exact N (N is constant and equal for all files) columns, so I want to match only some of them, without writing something like case Array(item1, item2 , ..., itemN) => List(item1, item2, itemK, itemN)

Thank you!

1 Answer 1

3

You do not need to convert lists to Arrays, because lists are designed for pattern matching.

scala> myList match { 
  case item :: site :: buyer :: tail if tail.nonEmpty => 
    item :: site :: buyer :: List(tail.last)
}
res3: List[List[Int]] = List(List(3, 1, 2, 3, 4), List(23, 45, 6, 7, 2), 
  List(3, 3, 2, 1, 5, 34, 43, 2), List(3, 2, 45, 56))

Or even more concise solution suggested by Kolmar

scala> myList match { 
  case item :: site :: buyer :: (_ :+ date) => List(item, site, buyer, date) 
}
Sign up to request clarification or add additional context in comments.

3 Comments

You'll want to add an if(tail.nonEmpty), otherwise this will match List(1, 2, 3), but throw a NoSuchElementException when you call tail.last.
Or just use myList match { case item :: site :: buyer :: (_ :+ date) => List(item, site, buyer, date) }
@Kolmar Wow, that's even better then my original suggestion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.