I am only beggining programming in Scala or functional programming. I was supposed to write a function that would filter a list of strings (the first line of main was given in the exercise). It is supposed to return words "Hello people". I have managed it with using variable but my teacher told me to modify it to not use any var. I've been trying to do that but I have no idea why the code below keeps returning an error. I'd appreciate any help because I am stumped.
main.scala:13: error: type mismatch;
found : Unit
required: List[String]
if(filter(workList.head))
^
1 error
exit status 1
object Main {
def main(args: Array[String]): Unit = {
println(filterList(List("Hello", "there", "people"), _.contains('l')).mkString(" "))
}
def filterList(listToSort:List[String], filter: (String) => Boolean): List[String] = {
@scala.annotation.tailrec
def recFilter(workList: List[String], filteredList: List[String]): List[String] = {
if(workList.isEmpty)
return filteredList
if(filter(workList.head))
recFilter(workList.tail, workList.head :: filteredList)
}
return recFilter(listToSort, List())
}
}
CodePudding user response:
I'm not sure exactly what the parameters of the excercise are, but the standard collections library in scala can do quite a bit for you...
In this case, List actually has a filter method already...
List("Hello", "there", "people").filter(_.contains("l"))
It may be worth skimming through tab completion on such a list and reading the docs on the suggestions.
If the excercise is to write your own, then obviously, this isn't the most helpful answer ever, and apologies for that. Another idea might be something like this;
def filterList(aList: List[String]) = {
for (
word <- aList
if word.contains("l")
) yield {
word
}
}
val filtered = filterList(testList)
Which is an intro to for yield syntax...
CodePudding user response:
Here's an approach using a recursion with a helper function and pattern matching.
def filterList(xs: List[String], filter: String => Boolean): List[String] = {
@scala.annotation.tailrec
def filterListR(xs: List[String], filter: String => Boolean, acc: List[String]): List[String] = xs match{
case Nil => acc
case head::tail if(filter(head)) => filterListR(tail, filter, head :: acc)
case head::tail => filterListR(tail, filter, acc)
}
filterListR(xs, filter, List[String]()).reverse
}
Output:
scala> filterList(List("Hello", "there", "people"), (s: String) => s.contains("l"))
val res3: List[String] = List(Hello, people)