Сравнение шаблонов списка для возврата нового списка каждого другого элемента - PullRequest
2 голосов
/ 15 мая 2019

Мне нужно написать функцию, которая принимает список, такой как («1», «2», «3»), и возвращать все остальные элементы в этом списке в новый список, используя сопоставление с образцом. Что будет правильным оператором case, чтобы получить элемент head из списка, а затем найти все остальные элементы.

def everyOther[A](list: List[A]): List[A] =
     list match {
     case   _ => Nil
     case x::xs => 
}

Должен возвращаться новый список каждого 2-го элемента, начиная с элемента head

Ответы [ 3 ]

5 голосов
/ 15 мая 2019

Рекурс на помощь.

def everyOther[A](list: List[A]): List[A] = list match {
  case Nil => list
  case _ :: Nil => list
  case x :: _ :: xs => x :: everyOther(xs)
}
2 голосов
/ 15 мая 2019

Вот еще один способ использования grouped для захвата всех остальных элементов списка, начиная с 1-го элемента:

def everyOther[A](list: List[A]): List[A] =
  list.grouped(2).map(_.head).toList

everyOther(List(1, 2, 3, 4, 5))
// res1: List[Int] = List(1, 3, 5)

Чтобы захватить все остальные элементы, начиная со 2-го элемента, либо замените список на tail:

def everyOther2[A](list: List[A]): List[A] =
  list.tail.grouped(2).map(_.head).toList

или замените map на collect частичной функцией case/match:

def everyOther2[A](list: List[A]): List[A] =
  list.grouped(2).collect{ case List(_, x) => x }.toList
1 голос
/ 15 мая 2019

Другие ответы отличные, но это ката настолько забавное, что я просто хотел добавить свое собственное решение:

Создать объект экстрактора:

object EveryOther {
    def unapply[A](list: List[A]): Option[List[A]] = {
      Some(
         Stream.iterate(true)(!_) //create lazy infinite stream of true,false,true...
           .zip(list)
           .flatMap{
              case (true, x) => Some(x) //filter to take only odd tuples with true
              case _ => None   //could be replaced with Option.when from scala 2.13
           }.toList
         )    
    }
}

А затем просто используйте его в сопоставлении с образцом:

List(1,2,3,4,5,6) match {
   case EveryOther(x) => println(x) //1,3,5
}
...