Способ takeWhile Scala с метод использовать-foldleft и foldRight



Мне нужно сделать takeWhile (), используя foldLeft () и foldRight ().
Я придумал вот что:



def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
ls.foldLeft(List[Int]())(a,z) =>
if (p(z)) z :: a
else a)
}

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
ls.foldRight(List[Int]())(a,z) =>
if (p(a)) a :: z
else z)
}


, но метод использовать-foldleft, когда я называю



takeWhile(List(1,2,3,4,5), _< 3)
takeWhile(List(1,2,3,4,5), _> 4)
takeWhile(List(5,6,7,1,2,5), _> 4)


Он возвращает



List(2,1)
List(5)
List(5,7,6,5)


С foldRight я получаю



List(5)
List(5,6,7,5)


Но это должно быть



List(1,2)
List()
List(5,6,7)


Как заставить его остановиться, если условие не выполнено?

552   3  

3 ответов:

Один из способов сделать это следующий (почти так же, как вы это сделали):

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
    ls.foldLeft(List[Int]()){
      case (a,z) =>
      if (p(z)) z :: a
      else return a.reverse
    }
}

Выводится следующее:

List(1, 2)
List()
List(5, 6, 7)

return возвращается из метода takeWhile, поэтому он делает то, что вы хотите, потому что он останавливает операцию foldLeft.

Извините, что я изменил ваш код (другие скобки и т. д.), Но он не компилировался при копировании.

Здесь является одним способом получить метод использовать-foldleft() на работу. Это банально, но он делает свою работу, и это отправная точка:

def takeWhile(ls:List[Int], p:Int => Boolean): List[Int] = {
  ls.foldLeft((List[Int](), true)) {
    (a, z) =>
      if (a._2 && p(z)) (z :: a._1, a._2)
      else (a._1, false)
  }._1.reverse
}

Вот один, использующий foldRight (так как вы просили и то, и другое):

def takeWhile[T](list: List[T], p: T => Boolean) =
  list.foldRight(List.empty[T]){
    case (t, l) if p(t) => t :: l
    case (t, l) => Nil
  }

Он повторно инициализирует состояние в Nil всякий раз, когда находит значение, которое не следует принимать.

Comments

    Ничего не найдено.