Using map to create a copy of an array (with generic type) results in error [Scala]












1















I am trying to copy an array of generic type using maps.



class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

val internalCopy : Array[T] = arr.map(e => e) //This line


But I run it gives an error saying



found   : scala.collection.mutable.ArraySeq[T]
required: Array[T]
Note: implicit value comparison is not applicable here because it comes after the application point and it lacks an explicit result type
val internalCopy : Array[T] = arr.map(e => e)


I am not able to make sense of this.










share|improve this question























  • The problem you are referring to is well explained here.

    – Markus Appel
    Nov 15 '18 at 10:16











  • It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

    – Dima
    Nov 15 '18 at 12:26
















1















I am trying to copy an array of generic type using maps.



class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

val internalCopy : Array[T] = arr.map(e => e) //This line


But I run it gives an error saying



found   : scala.collection.mutable.ArraySeq[T]
required: Array[T]
Note: implicit value comparison is not applicable here because it comes after the application point and it lacks an explicit result type
val internalCopy : Array[T] = arr.map(e => e)


I am not able to make sense of this.










share|improve this question























  • The problem you are referring to is well explained here.

    – Markus Appel
    Nov 15 '18 at 10:16











  • It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

    – Dima
    Nov 15 '18 at 12:26














1












1








1








I am trying to copy an array of generic type using maps.



class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

val internalCopy : Array[T] = arr.map(e => e) //This line


But I run it gives an error saying



found   : scala.collection.mutable.ArraySeq[T]
required: Array[T]
Note: implicit value comparison is not applicable here because it comes after the application point and it lacks an explicit result type
val internalCopy : Array[T] = arr.map(e => e)


I am not able to make sense of this.










share|improve this question














I am trying to copy an array of generic type using maps.



class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

val internalCopy : Array[T] = arr.map(e => e) //This line


But I run it gives an error saying



found   : scala.collection.mutable.ArraySeq[T]
required: Array[T]
Note: implicit value comparison is not applicable here because it comes after the application point and it lacks an explicit result type
val internalCopy : Array[T] = arr.map(e => e)


I am not able to make sense of this.







scala implicit-conversion implicit






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 9:59









AshwinAshwin

4,5362282146




4,5362282146













  • The problem you are referring to is well explained here.

    – Markus Appel
    Nov 15 '18 at 10:16











  • It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

    – Dima
    Nov 15 '18 at 12:26



















  • The problem you are referring to is well explained here.

    – Markus Appel
    Nov 15 '18 at 10:16











  • It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

    – Dima
    Nov 15 '18 at 12:26

















The problem you are referring to is well explained here.

– Markus Appel
Nov 15 '18 at 10:16





The problem you are referring to is well explained here.

– Markus Appel
Nov 15 '18 at 10:16













It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

– Dima
Nov 15 '18 at 12:26





It's not really explained there. There is an answer showing a workaround, but no explanation of why this behavior exists.

– Dima
Nov 15 '18 at 12:26












2 Answers
2






active

oldest

votes


















1














So, the problem is that .map returns ArraySeq rather than Array when there is no type information for the array elements at compile time. This is because you need to have the actual class for the elements: Array.newInstance(clazz, numElements). When you specify the element type as just T, that's not available, so when you do .map it switches the container type to ArraySeq to work around that limitation.



One way around that is pass the class information down to your class:



class MaObj[T : ClassTag : Ordering](val arr : Array[T])


(this is equivalent to class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])



This passes an implicit parameter to the class, that lets it resolve the element type at run time.



Another way, if you really just want to copy the array without transforming its elements, you can just use .clone, as the other answer suggests. It is a lot more efficient too.



Or just use IndexedSeq instead of Array to begin with, it is better anyway.






share|improve this answer































    1














    Instead of using your approach of .map combined with the identity, you can easily copy the Array using .clone.



    Your code would look like this:



    class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

    val internalCopy: Array[T] = arr.clone

    }


    Try it out!



    I hope this helps.






    share|improve this answer
























    • As a comment, the elements of the array will still be referentially equivalent.

      – Markus Appel
      Nov 15 '18 at 10:15











    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%2f53316790%2fusing-map-to-create-a-copy-of-an-array-with-generic-type-results-in-error-sca%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









    1














    So, the problem is that .map returns ArraySeq rather than Array when there is no type information for the array elements at compile time. This is because you need to have the actual class for the elements: Array.newInstance(clazz, numElements). When you specify the element type as just T, that's not available, so when you do .map it switches the container type to ArraySeq to work around that limitation.



    One way around that is pass the class information down to your class:



    class MaObj[T : ClassTag : Ordering](val arr : Array[T])


    (this is equivalent to class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])



    This passes an implicit parameter to the class, that lets it resolve the element type at run time.



    Another way, if you really just want to copy the array without transforming its elements, you can just use .clone, as the other answer suggests. It is a lot more efficient too.



    Or just use IndexedSeq instead of Array to begin with, it is better anyway.






    share|improve this answer




























      1














      So, the problem is that .map returns ArraySeq rather than Array when there is no type information for the array elements at compile time. This is because you need to have the actual class for the elements: Array.newInstance(clazz, numElements). When you specify the element type as just T, that's not available, so when you do .map it switches the container type to ArraySeq to work around that limitation.



      One way around that is pass the class information down to your class:



      class MaObj[T : ClassTag : Ordering](val arr : Array[T])


      (this is equivalent to class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])



      This passes an implicit parameter to the class, that lets it resolve the element type at run time.



      Another way, if you really just want to copy the array without transforming its elements, you can just use .clone, as the other answer suggests. It is a lot more efficient too.



      Or just use IndexedSeq instead of Array to begin with, it is better anyway.






      share|improve this answer


























        1












        1








        1







        So, the problem is that .map returns ArraySeq rather than Array when there is no type information for the array elements at compile time. This is because you need to have the actual class for the elements: Array.newInstance(clazz, numElements). When you specify the element type as just T, that's not available, so when you do .map it switches the container type to ArraySeq to work around that limitation.



        One way around that is pass the class information down to your class:



        class MaObj[T : ClassTag : Ordering](val arr : Array[T])


        (this is equivalent to class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])



        This passes an implicit parameter to the class, that lets it resolve the element type at run time.



        Another way, if you really just want to copy the array without transforming its elements, you can just use .clone, as the other answer suggests. It is a lot more efficient too.



        Or just use IndexedSeq instead of Array to begin with, it is better anyway.






        share|improve this answer













        So, the problem is that .map returns ArraySeq rather than Array when there is no type information for the array elements at compile time. This is because you need to have the actual class for the elements: Array.newInstance(clazz, numElements). When you specify the element type as just T, that's not available, so when you do .map it switches the container type to ArraySeq to work around that limitation.



        One way around that is pass the class information down to your class:



        class MaObj[T : ClassTag : Ordering](val arr : Array[T])


        (this is equivalent to class MaObj[T](val arr: Array[T])(implicit ev1: ClassTag[T], ev2: Ordering[T])



        This passes an implicit parameter to the class, that lets it resolve the element type at run time.



        Another way, if you really just want to copy the array without transforming its elements, you can just use .clone, as the other answer suggests. It is a lot more efficient too.



        Or just use IndexedSeq instead of Array to begin with, it is better anyway.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 15 '18 at 12:46









        DimaDima

        25.4k32539




        25.4k32539

























            1














            Instead of using your approach of .map combined with the identity, you can easily copy the Array using .clone.



            Your code would look like this:



            class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

            val internalCopy: Array[T] = arr.clone

            }


            Try it out!



            I hope this helps.






            share|improve this answer
























            • As a comment, the elements of the array will still be referentially equivalent.

              – Markus Appel
              Nov 15 '18 at 10:15
















            1














            Instead of using your approach of .map combined with the identity, you can easily copy the Array using .clone.



            Your code would look like this:



            class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

            val internalCopy: Array[T] = arr.clone

            }


            Try it out!



            I hope this helps.






            share|improve this answer
























            • As a comment, the elements of the array will still be referentially equivalent.

              – Markus Appel
              Nov 15 '18 at 10:15














            1












            1








            1







            Instead of using your approach of .map combined with the identity, you can easily copy the Array using .clone.



            Your code would look like this:



            class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

            val internalCopy: Array[T] = arr.clone

            }


            Try it out!



            I hope this helps.






            share|improve this answer













            Instead of using your approach of .map combined with the identity, you can easily copy the Array using .clone.



            Your code would look like this:



            class MaObj[T](val arr : Array[T])(implicit ordering : Ordering[T]) {

            val internalCopy: Array[T] = arr.clone

            }


            Try it out!



            I hope this helps.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 15 '18 at 10:10









            Markus AppelMarkus Appel

            952220




            952220













            • As a comment, the elements of the array will still be referentially equivalent.

              – Markus Appel
              Nov 15 '18 at 10:15



















            • As a comment, the elements of the array will still be referentially equivalent.

              – Markus Appel
              Nov 15 '18 at 10:15

















            As a comment, the elements of the array will still be referentially equivalent.

            – Markus Appel
            Nov 15 '18 at 10:15





            As a comment, the elements of the array will still be referentially equivalent.

            – Markus Appel
            Nov 15 '18 at 10:15


















            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%2f53316790%2fusing-map-to-create-a-copy-of-an-array-with-generic-type-results-in-error-sca%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

            Florida Star v. B. J. F.

            Error while running script in elastic search , gateway timeout

            Adding quotations to stringified JSON object values