scala: function which removes elements out of a list with a bigger predecessor












0















I want to write a tail-recursive function in scala biggerPredecessor which removes elements out of a list which have a bigger predecessor.



for example:



(1,3,2,5,7)


should result in:



(1,3,5,7)


Here is what I have so far but now I got stuck.



def biggerPredecessor(xs: List[Int]) : List[Int] = (xs) match
{
def finalElements(ys: List[Int], xs: List[Int]) : List[Int] = (ys, xs) match
{
case (Nil, x::xs) => finalElements(new List(x), xs)
case (y::ys, x::xs) if x > y => x::xs // insert in reverse order into list
case (y::ys, Nil) => // ...
}
}









share|improve this question























  • Does it need to be this complex?

    – erip
    Nov 19 '18 at 15:50











  • I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

    – jwvh
    Nov 19 '18 at 20:39
















0















I want to write a tail-recursive function in scala biggerPredecessor which removes elements out of a list which have a bigger predecessor.



for example:



(1,3,2,5,7)


should result in:



(1,3,5,7)


Here is what I have so far but now I got stuck.



def biggerPredecessor(xs: List[Int]) : List[Int] = (xs) match
{
def finalElements(ys: List[Int], xs: List[Int]) : List[Int] = (ys, xs) match
{
case (Nil, x::xs) => finalElements(new List(x), xs)
case (y::ys, x::xs) if x > y => x::xs // insert in reverse order into list
case (y::ys, Nil) => // ...
}
}









share|improve this question























  • Does it need to be this complex?

    – erip
    Nov 19 '18 at 15:50











  • I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

    – jwvh
    Nov 19 '18 at 20:39














0












0








0


1






I want to write a tail-recursive function in scala biggerPredecessor which removes elements out of a list which have a bigger predecessor.



for example:



(1,3,2,5,7)


should result in:



(1,3,5,7)


Here is what I have so far but now I got stuck.



def biggerPredecessor(xs: List[Int]) : List[Int] = (xs) match
{
def finalElements(ys: List[Int], xs: List[Int]) : List[Int] = (ys, xs) match
{
case (Nil, x::xs) => finalElements(new List(x), xs)
case (y::ys, x::xs) if x > y => x::xs // insert in reverse order into list
case (y::ys, Nil) => // ...
}
}









share|improve this question














I want to write a tail-recursive function in scala biggerPredecessor which removes elements out of a list which have a bigger predecessor.



for example:



(1,3,2,5,7)


should result in:



(1,3,5,7)


Here is what I have so far but now I got stuck.



def biggerPredecessor(xs: List[Int]) : List[Int] = (xs) match
{
def finalElements(ys: List[Int], xs: List[Int]) : List[Int] = (ys, xs) match
{
case (Nil, x::xs) => finalElements(new List(x), xs)
case (y::ys, x::xs) if x > y => x::xs // insert in reverse order into list
case (y::ys, Nil) => // ...
}
}






scala






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 15:45









johnnydasjohnnydas

31




31













  • Does it need to be this complex?

    – erip
    Nov 19 '18 at 15:50











  • I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

    – jwvh
    Nov 19 '18 at 20:39



















  • Does it need to be this complex?

    – erip
    Nov 19 '18 at 15:50











  • I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

    – jwvh
    Nov 19 '18 at 20:39

















Does it need to be this complex?

– erip
Nov 19 '18 at 15:50





Does it need to be this complex?

– erip
Nov 19 '18 at 15:50













I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

– jwvh
Nov 19 '18 at 20:39





I assume that for input List(5,3,4,6) the correct result should be List(5,6) and not List(5,4,6). Not all the answers provided so far produce this result.

– jwvh
Nov 19 '18 at 20:39












4 Answers
4






active

oldest

votes


















2














You could do something like this:



def biggerPredecessor(xs: List[Int]): List[Int] = {
@tailrec
def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
case Nil => acc
case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
}

finalElements(xs, List.empty[Int]).reverse
}


Or a bit more concise, using foldLeft:



foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))





share|improve this answer































    2














    My solution would go with foldLeft:



      val seq = List(1,3,2,5,7)

    val result = seq.foldLeft(List[Int]()){
    case (Nil, x: Int) => List(x)
    case (ys, x) if x > ys.last => ys :+ x
    case (ys, x) => ys
    }

    println(result)


    Here the version suggested by Luis Miguel Mejía Suárez:



     val result2 = seq.foldLeft(List.empty[Int]){
    case (Nil, x) => List(x)
    case (ys, x) if x > ys.head => x :: ys
    case (ys, x) => ys
    }.reverse


    Ok, here the recursive translation suggested by jwvh:



      def biggerPredecessor(list: List[Int],
    results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
    case (Nil, _) => results.reverse
    case (x::xs, Nil) => biggerPredecessor(xs, List(x))
    case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
    case (_::xs, _) => biggerPredecessor(xs, results)
    }

    println(biggerPredecessor(seq))


    This needs one more case, when the list is done.



    You can paste this in Scalafiddle and check yourself.






    share|improve this answer


























    • Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

      – Luis Miguel Mejía Suárez
      Nov 19 '18 at 16:23













    • @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

      – pme
      Nov 19 '18 at 16:31











    • The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

      – jwvh
      Nov 19 '18 at 21:45











    • Nicely done! (You misspelled "Predecessor.")

      – jwvh
      Nov 20 '18 at 8:20



















    1














    if you just need non-recursive solution then here it is:



    def biggerPredecessor(ls: List[Int]) =
    ls.take(1) ++ ls
    .zip(ls.drop(1))
    .collect {
    case (l,r) if !(l>r) => r
    }





    share|improve this answer





















    • 3





      I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

      – erip
      Nov 19 '18 at 16:00











    • fixed that, but now it looks a bit less cool though)

      – Bogdan Vakulenko
      Nov 19 '18 at 17:15











    • @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

      – Tim
      Nov 19 '18 at 19:04













    • @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

      – Bogdan Vakulenko
      Nov 19 '18 at 20:08











    • @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

      – Tim
      Nov 19 '18 at 22:09



















    0














    I am a big fan of the sliding function:



    def biggerPredecessor(xs: List[Int]) : List[Int] =
    (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
    .sliding(2)
    .flatMap {
    case List(a,b) => if (a > b) None else Some(b)
    case List(_) => None // special handling for empty xs
    }
    .toList


    println(biggerPredecessor(List()))
    println(biggerPredecessor(List(1)))
    println(biggerPredecessor(List(1,2)))
    println(biggerPredecessor(List(2,1)))
    println(biggerPredecessor(List(1,3,2,5,7)))


    ScalaFiddle






    share|improve this answer
























    • Wouldn't Int.MinValue make more sense as the sentinel?

      – jwvh
      Nov 19 '18 at 20:35











    • Yes, that would make more sense

      – ygor
      Nov 19 '18 at 21:51











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378160%2fscala-function-which-removes-elements-out-of-a-list-with-a-bigger-predecessor%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    You could do something like this:



    def biggerPredecessor(xs: List[Int]): List[Int] = {
    @tailrec
    def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
    case Nil => acc
    case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
    }

    finalElements(xs, List.empty[Int]).reverse
    }


    Or a bit more concise, using foldLeft:



    foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))





    share|improve this answer




























      2














      You could do something like this:



      def biggerPredecessor(xs: List[Int]): List[Int] = {
      @tailrec
      def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
      case Nil => acc
      case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
      }

      finalElements(xs, List.empty[Int]).reverse
      }


      Or a bit more concise, using foldLeft:



      foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))





      share|improve this answer


























        2












        2








        2







        You could do something like this:



        def biggerPredecessor(xs: List[Int]): List[Int] = {
        @tailrec
        def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
        case Nil => acc
        case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
        }

        finalElements(xs, List.empty[Int]).reverse
        }


        Or a bit more concise, using foldLeft:



        foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))





        share|improve this answer













        You could do something like this:



        def biggerPredecessor(xs: List[Int]): List[Int] = {
        @tailrec
        def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
        case Nil => acc
        case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
        }

        finalElements(xs, List.empty[Int]).reverse
        }


        Or a bit more concise, using foldLeft:



        foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 '18 at 15:57









        hasumedichasumedic

        1,981715




        1,981715

























            2














            My solution would go with foldLeft:



              val seq = List(1,3,2,5,7)

            val result = seq.foldLeft(List[Int]()){
            case (Nil, x: Int) => List(x)
            case (ys, x) if x > ys.last => ys :+ x
            case (ys, x) => ys
            }

            println(result)


            Here the version suggested by Luis Miguel Mejía Suárez:



             val result2 = seq.foldLeft(List.empty[Int]){
            case (Nil, x) => List(x)
            case (ys, x) if x > ys.head => x :: ys
            case (ys, x) => ys
            }.reverse


            Ok, here the recursive translation suggested by jwvh:



              def biggerPredecessor(list: List[Int],
            results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
            case (Nil, _) => results.reverse
            case (x::xs, Nil) => biggerPredecessor(xs, List(x))
            case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
            case (_::xs, _) => biggerPredecessor(xs, results)
            }

            println(biggerPredecessor(seq))


            This needs one more case, when the list is done.



            You can paste this in Scalafiddle and check yourself.






            share|improve this answer


























            • Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

              – Luis Miguel Mejía Suárez
              Nov 19 '18 at 16:23













            • @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

              – pme
              Nov 19 '18 at 16:31











            • The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

              – jwvh
              Nov 19 '18 at 21:45











            • Nicely done! (You misspelled "Predecessor.")

              – jwvh
              Nov 20 '18 at 8:20
















            2














            My solution would go with foldLeft:



              val seq = List(1,3,2,5,7)

            val result = seq.foldLeft(List[Int]()){
            case (Nil, x: Int) => List(x)
            case (ys, x) if x > ys.last => ys :+ x
            case (ys, x) => ys
            }

            println(result)


            Here the version suggested by Luis Miguel Mejía Suárez:



             val result2 = seq.foldLeft(List.empty[Int]){
            case (Nil, x) => List(x)
            case (ys, x) if x > ys.head => x :: ys
            case (ys, x) => ys
            }.reverse


            Ok, here the recursive translation suggested by jwvh:



              def biggerPredecessor(list: List[Int],
            results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
            case (Nil, _) => results.reverse
            case (x::xs, Nil) => biggerPredecessor(xs, List(x))
            case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
            case (_::xs, _) => biggerPredecessor(xs, results)
            }

            println(biggerPredecessor(seq))


            This needs one more case, when the list is done.



            You can paste this in Scalafiddle and check yourself.






            share|improve this answer


























            • Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

              – Luis Miguel Mejía Suárez
              Nov 19 '18 at 16:23













            • @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

              – pme
              Nov 19 '18 at 16:31











            • The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

              – jwvh
              Nov 19 '18 at 21:45











            • Nicely done! (You misspelled "Predecessor.")

              – jwvh
              Nov 20 '18 at 8:20














            2












            2








            2







            My solution would go with foldLeft:



              val seq = List(1,3,2,5,7)

            val result = seq.foldLeft(List[Int]()){
            case (Nil, x: Int) => List(x)
            case (ys, x) if x > ys.last => ys :+ x
            case (ys, x) => ys
            }

            println(result)


            Here the version suggested by Luis Miguel Mejía Suárez:



             val result2 = seq.foldLeft(List.empty[Int]){
            case (Nil, x) => List(x)
            case (ys, x) if x > ys.head => x :: ys
            case (ys, x) => ys
            }.reverse


            Ok, here the recursive translation suggested by jwvh:



              def biggerPredecessor(list: List[Int],
            results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
            case (Nil, _) => results.reverse
            case (x::xs, Nil) => biggerPredecessor(xs, List(x))
            case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
            case (_::xs, _) => biggerPredecessor(xs, results)
            }

            println(biggerPredecessor(seq))


            This needs one more case, when the list is done.



            You can paste this in Scalafiddle and check yourself.






            share|improve this answer















            My solution would go with foldLeft:



              val seq = List(1,3,2,5,7)

            val result = seq.foldLeft(List[Int]()){
            case (Nil, x: Int) => List(x)
            case (ys, x) if x > ys.last => ys :+ x
            case (ys, x) => ys
            }

            println(result)


            Here the version suggested by Luis Miguel Mejía Suárez:



             val result2 = seq.foldLeft(List.empty[Int]){
            case (Nil, x) => List(x)
            case (ys, x) if x > ys.head => x :: ys
            case (ys, x) => ys
            }.reverse


            Ok, here the recursive translation suggested by jwvh:



              def biggerPredecessor(list: List[Int],
            results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
            case (Nil, _) => results.reverse
            case (x::xs, Nil) => biggerPredecessor(xs, List(x))
            case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
            case (_::xs, _) => biggerPredecessor(xs, results)
            }

            println(biggerPredecessor(seq))


            This needs one more case, when the list is done.



            You can paste this in Scalafiddle and check yourself.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 '18 at 9:40

























            answered Nov 19 '18 at 16:03









            pmepme

            2,45511224




            2,45511224













            • Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

              – Luis Miguel Mejía Suárez
              Nov 19 '18 at 16:23













            • @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

              – pme
              Nov 19 '18 at 16:31











            • The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

              – jwvh
              Nov 19 '18 at 21:45











            • Nicely done! (You misspelled "Predecessor.")

              – jwvh
              Nov 20 '18 at 8:20



















            • Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

              – Luis Miguel Mejía Suárez
              Nov 19 '18 at 16:23













            • @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

              – pme
              Nov 19 '18 at 16:31











            • The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

              – jwvh
              Nov 19 '18 at 21:45











            • Nicely done! (You misspelled "Predecessor.")

              – jwvh
              Nov 20 '18 at 8:20

















            Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

            – Luis Miguel Mejía Suárez
            Nov 19 '18 at 16:23







            Nice solution, just a few things. First, it would be more optimal to just build the target list backwards (using :: and head instead of :+ and last) and then reverse it at the end. Second, you don't need to specify that x is an Int in your first case. Finally, I think is more readable and common to use List.empty[Int] than List[Int]() .

            – Luis Miguel Mejía Suárez
            Nov 19 '18 at 16:23















            @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

            – pme
            Nov 19 '18 at 16:31





            @LuisMiguelMejíaSuárez: thanks for your comment - I added your suggestion.

            – pme
            Nov 19 '18 at 16:31













            The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

            – jwvh
            Nov 19 '18 at 21:45





            The only answer (so far) that handles input List(-2,-4,-3,-1) correctly. It is not, however, recursive as the OP requested.

            – jwvh
            Nov 19 '18 at 21:45













            Nicely done! (You misspelled "Predecessor.")

            – jwvh
            Nov 20 '18 at 8:20





            Nicely done! (You misspelled "Predecessor.")

            – jwvh
            Nov 20 '18 at 8:20











            1














            if you just need non-recursive solution then here it is:



            def biggerPredecessor(ls: List[Int]) =
            ls.take(1) ++ ls
            .zip(ls.drop(1))
            .collect {
            case (l,r) if !(l>r) => r
            }





            share|improve this answer





















            • 3





              I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

              – erip
              Nov 19 '18 at 16:00











            • fixed that, but now it looks a bit less cool though)

              – Bogdan Vakulenko
              Nov 19 '18 at 17:15











            • @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

              – Tim
              Nov 19 '18 at 19:04













            • @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

              – Bogdan Vakulenko
              Nov 19 '18 at 20:08











            • @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

              – Tim
              Nov 19 '18 at 22:09
















            1














            if you just need non-recursive solution then here it is:



            def biggerPredecessor(ls: List[Int]) =
            ls.take(1) ++ ls
            .zip(ls.drop(1))
            .collect {
            case (l,r) if !(l>r) => r
            }





            share|improve this answer





















            • 3





              I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

              – erip
              Nov 19 '18 at 16:00











            • fixed that, but now it looks a bit less cool though)

              – Bogdan Vakulenko
              Nov 19 '18 at 17:15











            • @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

              – Tim
              Nov 19 '18 at 19:04













            • @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

              – Bogdan Vakulenko
              Nov 19 '18 at 20:08











            • @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

              – Tim
              Nov 19 '18 at 22:09














            1












            1








            1







            if you just need non-recursive solution then here it is:



            def biggerPredecessor(ls: List[Int]) =
            ls.take(1) ++ ls
            .zip(ls.drop(1))
            .collect {
            case (l,r) if !(l>r) => r
            }





            share|improve this answer















            if you just need non-recursive solution then here it is:



            def biggerPredecessor(ls: List[Int]) =
            ls.take(1) ++ ls
            .zip(ls.drop(1))
            .collect {
            case (l,r) if !(l>r) => r
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 20 '18 at 4:51

























            answered Nov 19 '18 at 15:57









            Bogdan VakulenkoBogdan Vakulenko

            1,001214




            1,001214








            • 3





              I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

              – erip
              Nov 19 '18 at 16:00











            • fixed that, but now it looks a bit less cool though)

              – Bogdan Vakulenko
              Nov 19 '18 at 17:15











            • @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

              – Tim
              Nov 19 '18 at 19:04













            • @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

              – Bogdan Vakulenko
              Nov 19 '18 at 20:08











            • @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

              – Tim
              Nov 19 '18 at 22:09














            • 3





              I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

              – erip
              Nov 19 '18 at 16:00











            • fixed that, but now it looks a bit less cool though)

              – Bogdan Vakulenko
              Nov 19 '18 at 17:15











            • @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

              – Tim
              Nov 19 '18 at 19:04













            • @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

              – Bogdan Vakulenko
              Nov 19 '18 at 20:08











            • @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

              – Tim
              Nov 19 '18 at 22:09








            3




            3





            I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

            – erip
            Nov 19 '18 at 16:00





            I love the approach. Just a hint, though: there's trouble in paradise when the sequence is empty.

            – erip
            Nov 19 '18 at 16:00













            fixed that, but now it looks a bit less cool though)

            – Bogdan Vakulenko
            Nov 19 '18 at 17:15





            fixed that, but now it looks a bit less cool though)

            – Bogdan Vakulenko
            Nov 19 '18 at 17:15













            @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

            – Tim
            Nov 19 '18 at 19:04







            @BogdanVakulenko Using take(1) and drop(1) might be cleaner than using headOption and getOrElse. take and drop are almost always a safer option than head and tail.

            – Tim
            Nov 19 '18 at 19:04















            @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

            – Bogdan Vakulenko
            Nov 19 '18 at 20:08





            @Tim thanks. fixed the answer. it looks more elegant with take/drop. but probably a bit slower because of ++ instead of ::

            – Bogdan Vakulenko
            Nov 19 '18 at 20:08













            @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

            – Tim
            Nov 19 '18 at 22:09





            @BogdanVakulenko You could also use collect with a guard on the case to replace both the filter and map.

            – Tim
            Nov 19 '18 at 22:09











            0














            I am a big fan of the sliding function:



            def biggerPredecessor(xs: List[Int]) : List[Int] =
            (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
            .sliding(2)
            .flatMap {
            case List(a,b) => if (a > b) None else Some(b)
            case List(_) => None // special handling for empty xs
            }
            .toList


            println(biggerPredecessor(List()))
            println(biggerPredecessor(List(1)))
            println(biggerPredecessor(List(1,2)))
            println(biggerPredecessor(List(2,1)))
            println(biggerPredecessor(List(1,3,2,5,7)))


            ScalaFiddle






            share|improve this answer
























            • Wouldn't Int.MinValue make more sense as the sentinel?

              – jwvh
              Nov 19 '18 at 20:35











            • Yes, that would make more sense

              – ygor
              Nov 19 '18 at 21:51
















            0














            I am a big fan of the sliding function:



            def biggerPredecessor(xs: List[Int]) : List[Int] =
            (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
            .sliding(2)
            .flatMap {
            case List(a,b) => if (a > b) None else Some(b)
            case List(_) => None // special handling for empty xs
            }
            .toList


            println(biggerPredecessor(List()))
            println(biggerPredecessor(List(1)))
            println(biggerPredecessor(List(1,2)))
            println(biggerPredecessor(List(2,1)))
            println(biggerPredecessor(List(1,3,2,5,7)))


            ScalaFiddle






            share|improve this answer
























            • Wouldn't Int.MinValue make more sense as the sentinel?

              – jwvh
              Nov 19 '18 at 20:35











            • Yes, that would make more sense

              – ygor
              Nov 19 '18 at 21:51














            0












            0








            0







            I am a big fan of the sliding function:



            def biggerPredecessor(xs: List[Int]) : List[Int] =
            (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
            .sliding(2)
            .flatMap {
            case List(a,b) => if (a > b) None else Some(b)
            case List(_) => None // special handling for empty xs
            }
            .toList


            println(biggerPredecessor(List()))
            println(biggerPredecessor(List(1)))
            println(biggerPredecessor(List(1,2)))
            println(biggerPredecessor(List(2,1)))
            println(biggerPredecessor(List(1,3,2,5,7)))


            ScalaFiddle






            share|improve this answer













            I am a big fan of the sliding function:



            def biggerPredecessor(xs: List[Int]) : List[Int] =
            (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
            .sliding(2)
            .flatMap {
            case List(a,b) => if (a > b) None else Some(b)
            case List(_) => None // special handling for empty xs
            }
            .toList


            println(biggerPredecessor(List()))
            println(biggerPredecessor(List(1)))
            println(biggerPredecessor(List(1,2)))
            println(biggerPredecessor(List(2,1)))
            println(biggerPredecessor(List(1,3,2,5,7)))


            ScalaFiddle







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 19 '18 at 18:10









            ygorygor

            1,112615




            1,112615













            • Wouldn't Int.MinValue make more sense as the sentinel?

              – jwvh
              Nov 19 '18 at 20:35











            • Yes, that would make more sense

              – ygor
              Nov 19 '18 at 21:51



















            • Wouldn't Int.MinValue make more sense as the sentinel?

              – jwvh
              Nov 19 '18 at 20:35











            • Yes, that would make more sense

              – ygor
              Nov 19 '18 at 21:51

















            Wouldn't Int.MinValue make more sense as the sentinel?

            – jwvh
            Nov 19 '18 at 20:35





            Wouldn't Int.MinValue make more sense as the sentinel?

            – jwvh
            Nov 19 '18 at 20:35













            Yes, that would make more sense

            – ygor
            Nov 19 '18 at 21:51





            Yes, that would make more sense

            – ygor
            Nov 19 '18 at 21:51


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53378160%2fscala-function-which-removes-elements-out-of-a-list-with-a-bigger-predecessor%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?