Scala: Find and update one element in a list





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







2















I am trying to find an elegant way to do:



val l = List(1,2,3)

val (item, idx) = l.zipWithIndex.find(predicate)

val updatedItem = updating(item)

l.update(idx, updatedItem)


Can I do all in one operation ? Find the item, if it exist replace with updated value and keep it in place.



I could do:



l.map{ i => 
if (predicate(i)) {
updating(i)
} else {
i
}
}


but that's pretty ugly.



The other complexity is the fact that I want to update only the first element which match predicate .



Edit: Attempt:



implicit class UpdateList[A](l: List[A]) {
def filterMap(p: A => Boolean)(update: A => A): List[A] = {
l.map(a => if (p(a)) update(a) else a)
}

def updateFirst(p: A => Boolean)(update: A => A): List[A] = {
val found = l.zipWithIndex.find { case (item, _) => p(item) }
found match {
case Some((item, idx)) => l.updated(idx, update(item))
case None => l
}
}
}









share|improve this question

























  • I just realized the issue haha. I only want to do it on the first item found.

    – Wonay
    Jan 3 at 2:50






  • 1





    Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

    – Luis Miguel Mejía Suárez
    Jan 3 at 2:58













  • then I feel than my updateFirst method is the best so far ?

    – Wonay
    Jan 3 at 3:04






  • 1





    Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

    – Luis Miguel Mejía Suárez
    Jan 3 at 3:12













  • How would that work with a vector ?

    – Wonay
    Jan 3 at 4:16


















2















I am trying to find an elegant way to do:



val l = List(1,2,3)

val (item, idx) = l.zipWithIndex.find(predicate)

val updatedItem = updating(item)

l.update(idx, updatedItem)


Can I do all in one operation ? Find the item, if it exist replace with updated value and keep it in place.



I could do:



l.map{ i => 
if (predicate(i)) {
updating(i)
} else {
i
}
}


but that's pretty ugly.



The other complexity is the fact that I want to update only the first element which match predicate .



Edit: Attempt:



implicit class UpdateList[A](l: List[A]) {
def filterMap(p: A => Boolean)(update: A => A): List[A] = {
l.map(a => if (p(a)) update(a) else a)
}

def updateFirst(p: A => Boolean)(update: A => A): List[A] = {
val found = l.zipWithIndex.find { case (item, _) => p(item) }
found match {
case Some((item, idx)) => l.updated(idx, update(item))
case None => l
}
}
}









share|improve this question

























  • I just realized the issue haha. I only want to do it on the first item found.

    – Wonay
    Jan 3 at 2:50






  • 1





    Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

    – Luis Miguel Mejía Suárez
    Jan 3 at 2:58













  • then I feel than my updateFirst method is the best so far ?

    – Wonay
    Jan 3 at 3:04






  • 1





    Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

    – Luis Miguel Mejía Suárez
    Jan 3 at 3:12













  • How would that work with a vector ?

    – Wonay
    Jan 3 at 4:16














2












2








2


1






I am trying to find an elegant way to do:



val l = List(1,2,3)

val (item, idx) = l.zipWithIndex.find(predicate)

val updatedItem = updating(item)

l.update(idx, updatedItem)


Can I do all in one operation ? Find the item, if it exist replace with updated value and keep it in place.



I could do:



l.map{ i => 
if (predicate(i)) {
updating(i)
} else {
i
}
}


but that's pretty ugly.



The other complexity is the fact that I want to update only the first element which match predicate .



Edit: Attempt:



implicit class UpdateList[A](l: List[A]) {
def filterMap(p: A => Boolean)(update: A => A): List[A] = {
l.map(a => if (p(a)) update(a) else a)
}

def updateFirst(p: A => Boolean)(update: A => A): List[A] = {
val found = l.zipWithIndex.find { case (item, _) => p(item) }
found match {
case Some((item, idx)) => l.updated(idx, update(item))
case None => l
}
}
}









share|improve this question
















I am trying to find an elegant way to do:



val l = List(1,2,3)

val (item, idx) = l.zipWithIndex.find(predicate)

val updatedItem = updating(item)

l.update(idx, updatedItem)


Can I do all in one operation ? Find the item, if it exist replace with updated value and keep it in place.



I could do:



l.map{ i => 
if (predicate(i)) {
updating(i)
} else {
i
}
}


but that's pretty ugly.



The other complexity is the fact that I want to update only the first element which match predicate .



Edit: Attempt:



implicit class UpdateList[A](l: List[A]) {
def filterMap(p: A => Boolean)(update: A => A): List[A] = {
l.map(a => if (p(a)) update(a) else a)
}

def updateFirst(p: A => Boolean)(update: A => A): List[A] = {
val found = l.zipWithIndex.find { case (item, _) => p(item) }
found match {
case Some((item, idx)) => l.updated(idx, update(item))
case None => l
}
}
}






scala functional-programming scalaz






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 2:54







Wonay

















asked Jan 3 at 2:34









WonayWonay

399213




399213













  • I just realized the issue haha. I only want to do it on the first item found.

    – Wonay
    Jan 3 at 2:50






  • 1





    Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

    – Luis Miguel Mejía Suárez
    Jan 3 at 2:58













  • then I feel than my updateFirst method is the best so far ?

    – Wonay
    Jan 3 at 3:04






  • 1





    Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

    – Luis Miguel Mejía Suárez
    Jan 3 at 3:12













  • How would that work with a vector ?

    – Wonay
    Jan 3 at 4:16



















  • I just realized the issue haha. I only want to do it on the first item found.

    – Wonay
    Jan 3 at 2:50






  • 1





    Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

    – Luis Miguel Mejía Suárez
    Jan 3 at 2:58













  • then I feel than my updateFirst method is the best so far ?

    – Wonay
    Jan 3 at 3:04






  • 1





    Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

    – Luis Miguel Mejía Suárez
    Jan 3 at 3:12













  • How would that work with a vector ?

    – Wonay
    Jan 3 at 4:16

















I just realized the issue haha. I only want to do it on the first item found.

– Wonay
Jan 3 at 2:50





I just realized the issue haha. I only want to do it on the first item found.

– Wonay
Jan 3 at 2:50




1




1





Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

– Luis Miguel Mejía Suárez
Jan 3 at 2:58







Given that I can only think in having a mutable variable to track if an update already was made and do the map with if (!alreadyUpdated && predicate(i)) - you can encapsulate everything in a method to don't expose the mutable variable. For a completely immutable solution, I would use a foldLeft in which you accumulate the new List (backwards) and the flag of alreadyUpdated, after the fold you may extract the List and then reverse it - however it will have complexity 2O(N) (two iterations) and may be too complex. Not sure if there is a better way, that is why I dont answer

– Luis Miguel Mejía Suárez
Jan 3 at 2:58















then I feel than my updateFirst method is the best so far ?

– Wonay
Jan 3 at 3:04





then I feel than my updateFirst method is the best so far ?

– Wonay
Jan 3 at 3:04




1




1





Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

– Luis Miguel Mejía Suárez
Jan 3 at 3:12







Wonay, IMHO no. The intention is very clear that is a point! - but it does a lot of iterations (O(3N) in case the first element is near to the end) and creates one extra intermediate collection. If you're sure the collections will be small and the first item will be near the beginning it may not be so bad. Aki, I don't believe that is a good idea, because he/she needs the element too, thus it will need to call apply with that index again which will result in another iteration - but will make the intention more clear!, which is a point! Other idea would be to use Vector instead of List.

– Luis Miguel Mejía Suárez
Jan 3 at 3:12















How would that work with a vector ?

– Wonay
Jan 3 at 4:16





How would that work with a vector ?

– Wonay
Jan 3 at 4:16












2 Answers
2






active

oldest

votes


















3














I don't know any way to make this in one pass of the collection without using a mutable variable. With two passes you can do it using foldLeft as in:



def updateFirst[A](list:List[A])(predicate:A => Boolean, newValue:A):List[A] = {
list.foldLeft((List.empty[A], predicate))((acc, it) => {acc match {
case (nl,pr) => if (pr(it)) (newValue::nl, _ => false) else (it::nl, pr)
}})._1.reverse
}


The idea is that foldLeft allows passing additional data through iteration. In this particular implementation I change the predicate to the fixed one that always returns false. Unfortunately you can't build a List from the head in an efficient way so this requires another pass for reverse.



I believe it is obvious how to do it using a combination of map and var



Note: performance of the List.map is the same as of a single pass over the list only because internally the standard library is mutable. Particularly the cons class :: is declared as



final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {


so tl is actually a var and this is exploited by the map implementation to build a list from the head in an efficient way. The field is private[scala] so you can't use the same trick from outside of the standard library. Unfortunately I don't see any other API call that allows to use this feature to reduce the complexity of your problem to a single pass.






share|improve this answer

































    3














    You can avoid .zipWithIndex() by using .indexWhere().



    To improve complexity, use Vector so that l(idx) becomes effectively constant time.



    val l = Vector(1,2,3)
    val idx = l.indexWhere(predicate)
    val updatedItem = updating(l(idx))
    l.updated(idx, updatedItem)


    Reason for using scala.collection.immutable.Vector rather than List:
    Scala's List is a linked list, which means data are access in O(n) time. Scala's Vector is indexed, meaning data can be read from any point in effectively constant time.



    You may also consider mutable collections if you're modifying just one element in a very large collection.



    https://docs.scala-lang.org/overviews/collections/performance-characteristics.html






    share|improve this answer





















    • 1





      That's not better than the author's code because l(idx) is O(N)

      – SergGr
      Jan 3 at 3:14











    • Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

      – Wonay
      Jan 3 at 4:17






    • 1





      edited. code is exactly the same

      – Leighton Ritchie
      Jan 3 at 4:43






    • 1





      Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

      – Luis Miguel Mejía Suárez
      Jan 3 at 12:29












    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%2f54015611%2fscala-find-and-update-one-element-in-a-list%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    I don't know any way to make this in one pass of the collection without using a mutable variable. With two passes you can do it using foldLeft as in:



    def updateFirst[A](list:List[A])(predicate:A => Boolean, newValue:A):List[A] = {
    list.foldLeft((List.empty[A], predicate))((acc, it) => {acc match {
    case (nl,pr) => if (pr(it)) (newValue::nl, _ => false) else (it::nl, pr)
    }})._1.reverse
    }


    The idea is that foldLeft allows passing additional data through iteration. In this particular implementation I change the predicate to the fixed one that always returns false. Unfortunately you can't build a List from the head in an efficient way so this requires another pass for reverse.



    I believe it is obvious how to do it using a combination of map and var



    Note: performance of the List.map is the same as of a single pass over the list only because internally the standard library is mutable. Particularly the cons class :: is declared as



    final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {


    so tl is actually a var and this is exploited by the map implementation to build a list from the head in an efficient way. The field is private[scala] so you can't use the same trick from outside of the standard library. Unfortunately I don't see any other API call that allows to use this feature to reduce the complexity of your problem to a single pass.






    share|improve this answer






























      3














      I don't know any way to make this in one pass of the collection without using a mutable variable. With two passes you can do it using foldLeft as in:



      def updateFirst[A](list:List[A])(predicate:A => Boolean, newValue:A):List[A] = {
      list.foldLeft((List.empty[A], predicate))((acc, it) => {acc match {
      case (nl,pr) => if (pr(it)) (newValue::nl, _ => false) else (it::nl, pr)
      }})._1.reverse
      }


      The idea is that foldLeft allows passing additional data through iteration. In this particular implementation I change the predicate to the fixed one that always returns false. Unfortunately you can't build a List from the head in an efficient way so this requires another pass for reverse.



      I believe it is obvious how to do it using a combination of map and var



      Note: performance of the List.map is the same as of a single pass over the list only because internally the standard library is mutable. Particularly the cons class :: is declared as



      final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {


      so tl is actually a var and this is exploited by the map implementation to build a list from the head in an efficient way. The field is private[scala] so you can't use the same trick from outside of the standard library. Unfortunately I don't see any other API call that allows to use this feature to reduce the complexity of your problem to a single pass.






      share|improve this answer




























        3












        3








        3







        I don't know any way to make this in one pass of the collection without using a mutable variable. With two passes you can do it using foldLeft as in:



        def updateFirst[A](list:List[A])(predicate:A => Boolean, newValue:A):List[A] = {
        list.foldLeft((List.empty[A], predicate))((acc, it) => {acc match {
        case (nl,pr) => if (pr(it)) (newValue::nl, _ => false) else (it::nl, pr)
        }})._1.reverse
        }


        The idea is that foldLeft allows passing additional data through iteration. In this particular implementation I change the predicate to the fixed one that always returns false. Unfortunately you can't build a List from the head in an efficient way so this requires another pass for reverse.



        I believe it is obvious how to do it using a combination of map and var



        Note: performance of the List.map is the same as of a single pass over the list only because internally the standard library is mutable. Particularly the cons class :: is declared as



        final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {


        so tl is actually a var and this is exploited by the map implementation to build a list from the head in an efficient way. The field is private[scala] so you can't use the same trick from outside of the standard library. Unfortunately I don't see any other API call that allows to use this feature to reduce the complexity of your problem to a single pass.






        share|improve this answer















        I don't know any way to make this in one pass of the collection without using a mutable variable. With two passes you can do it using foldLeft as in:



        def updateFirst[A](list:List[A])(predicate:A => Boolean, newValue:A):List[A] = {
        list.foldLeft((List.empty[A], predicate))((acc, it) => {acc match {
        case (nl,pr) => if (pr(it)) (newValue::nl, _ => false) else (it::nl, pr)
        }})._1.reverse
        }


        The idea is that foldLeft allows passing additional data through iteration. In this particular implementation I change the predicate to the fixed one that always returns false. Unfortunately you can't build a List from the head in an efficient way so this requires another pass for reverse.



        I believe it is obvious how to do it using a combination of map and var



        Note: performance of the List.map is the same as of a single pass over the list only because internally the standard library is mutable. Particularly the cons class :: is declared as



        final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {


        so tl is actually a var and this is exploited by the map implementation to build a list from the head in an efficient way. The field is private[scala] so you can't use the same trick from outside of the standard library. Unfortunately I don't see any other API call that allows to use this feature to reduce the complexity of your problem to a single pass.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 3 at 3:26

























        answered Jan 3 at 3:18









        SergGrSergGr

        21.4k22243




        21.4k22243

























            3














            You can avoid .zipWithIndex() by using .indexWhere().



            To improve complexity, use Vector so that l(idx) becomes effectively constant time.



            val l = Vector(1,2,3)
            val idx = l.indexWhere(predicate)
            val updatedItem = updating(l(idx))
            l.updated(idx, updatedItem)


            Reason for using scala.collection.immutable.Vector rather than List:
            Scala's List is a linked list, which means data are access in O(n) time. Scala's Vector is indexed, meaning data can be read from any point in effectively constant time.



            You may also consider mutable collections if you're modifying just one element in a very large collection.



            https://docs.scala-lang.org/overviews/collections/performance-characteristics.html






            share|improve this answer





















            • 1





              That's not better than the author's code because l(idx) is O(N)

              – SergGr
              Jan 3 at 3:14











            • Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

              – Wonay
              Jan 3 at 4:17






            • 1





              edited. code is exactly the same

              – Leighton Ritchie
              Jan 3 at 4:43






            • 1





              Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

              – Luis Miguel Mejía Suárez
              Jan 3 at 12:29
















            3














            You can avoid .zipWithIndex() by using .indexWhere().



            To improve complexity, use Vector so that l(idx) becomes effectively constant time.



            val l = Vector(1,2,3)
            val idx = l.indexWhere(predicate)
            val updatedItem = updating(l(idx))
            l.updated(idx, updatedItem)


            Reason for using scala.collection.immutable.Vector rather than List:
            Scala's List is a linked list, which means data are access in O(n) time. Scala's Vector is indexed, meaning data can be read from any point in effectively constant time.



            You may also consider mutable collections if you're modifying just one element in a very large collection.



            https://docs.scala-lang.org/overviews/collections/performance-characteristics.html






            share|improve this answer





















            • 1





              That's not better than the author's code because l(idx) is O(N)

              – SergGr
              Jan 3 at 3:14











            • Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

              – Wonay
              Jan 3 at 4:17






            • 1





              edited. code is exactly the same

              – Leighton Ritchie
              Jan 3 at 4:43






            • 1





              Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

              – Luis Miguel Mejía Suárez
              Jan 3 at 12:29














            3












            3








            3







            You can avoid .zipWithIndex() by using .indexWhere().



            To improve complexity, use Vector so that l(idx) becomes effectively constant time.



            val l = Vector(1,2,3)
            val idx = l.indexWhere(predicate)
            val updatedItem = updating(l(idx))
            l.updated(idx, updatedItem)


            Reason for using scala.collection.immutable.Vector rather than List:
            Scala's List is a linked list, which means data are access in O(n) time. Scala's Vector is indexed, meaning data can be read from any point in effectively constant time.



            You may also consider mutable collections if you're modifying just one element in a very large collection.



            https://docs.scala-lang.org/overviews/collections/performance-characteristics.html






            share|improve this answer















            You can avoid .zipWithIndex() by using .indexWhere().



            To improve complexity, use Vector so that l(idx) becomes effectively constant time.



            val l = Vector(1,2,3)
            val idx = l.indexWhere(predicate)
            val updatedItem = updating(l(idx))
            l.updated(idx, updatedItem)


            Reason for using scala.collection.immutable.Vector rather than List:
            Scala's List is a linked list, which means data are access in O(n) time. Scala's Vector is indexed, meaning data can be read from any point in effectively constant time.



            You may also consider mutable collections if you're modifying just one element in a very large collection.



            https://docs.scala-lang.org/overviews/collections/performance-characteristics.html







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 3 at 4:42

























            answered Jan 3 at 3:13









            Leighton RitchieLeighton Ritchie

            556




            556








            • 1





              That's not better than the author's code because l(idx) is O(N)

              – SergGr
              Jan 3 at 3:14











            • Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

              – Wonay
              Jan 3 at 4:17






            • 1





              edited. code is exactly the same

              – Leighton Ritchie
              Jan 3 at 4:43






            • 1





              Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

              – Luis Miguel Mejía Suárez
              Jan 3 at 12:29














            • 1





              That's not better than the author's code because l(idx) is O(N)

              – SergGr
              Jan 3 at 3:14











            • Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

              – Wonay
              Jan 3 at 4:17






            • 1





              edited. code is exactly the same

              – Leighton Ritchie
              Jan 3 at 4:43






            • 1





              Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

              – Luis Miguel Mejía Suárez
              Jan 3 at 12:29








            1




            1





            That's not better than the author's code because l(idx) is O(N)

            – SergGr
            Jan 3 at 3:14





            That's not better than the author's code because l(idx) is O(N)

            – SergGr
            Jan 3 at 3:14













            Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

            – Wonay
            Jan 3 at 4:17





            Would you mind editing your solution with Vector ? Would any of the code change or just the performances ?

            – Wonay
            Jan 3 at 4:17




            1




            1





            edited. code is exactly the same

            – Leighton Ritchie
            Jan 3 at 4:43





            edited. code is exactly the same

            – Leighton Ritchie
            Jan 3 at 4:43




            1




            1





            Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

            – Luis Miguel Mejía Suárez
            Jan 3 at 12:29





            Wonay as Leighton already said the code will no change, but its performance will be sightly better. However be aware that Vectors are not as great as one expects

            – Luis Miguel Mejía Suárez
            Jan 3 at 12:29


















            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%2f54015611%2fscala-find-and-update-one-element-in-a-list%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

            Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

            ts Property 'filter' does not exist on type '{}'

            mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window