Using map to create a copy of an array (with generic type) results in error [Scala]
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
add a comment |
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
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
add a comment |
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
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
scala implicit-conversion implicit
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
add a comment |
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
add a comment |
2 Answers
2
active
oldest
votes
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.
add a comment |
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.
As a comment, the elements of the array will still be referentially equivalent.
– Markus Appel
Nov 15 '18 at 10:15
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 15 '18 at 12:46
DimaDima
25.4k32539
25.4k32539
add a comment |
add a comment |
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.
As a comment, the elements of the array will still be referentially equivalent.
– Markus Appel
Nov 15 '18 at 10:15
add a comment |
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.
As a comment, the elements of the array will still be referentially equivalent.
– Markus Appel
Nov 15 '18 at 10:15
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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