I got into that question by thinking about sorting algorithms.
Does changing an element position inside an array would be the same, at the interpretation, compilation or run-time phases, to recreate the entire array with new elements?
Does it change radically from one language to another?
How does it work?
Imagining a specific case in JavaScript, for example:
let animals = ["monkey","zebra","banana","capybara"];
animals.splice(2,1); // returns ["banana"]
Would it be correct to state that the entire animals
array was rewritten? Or is there another type of change type? How would that one and only change work, computation-wise?
It's stated in Javascript documentation that the .splice()
method "takes" an array object, creates a new array without it and returns another one with it as an output, but how does it work?
I'm a begginner, so please have patience, and would like a good reading recommendation if possible to learn more about it. Sorry for the incovenience.
CodePudding user response:
Does changing an element position inside an array would be the same, at the interpretation, compilation or run-time phases, to recreate the entire array with new elements?
I think you're asking this:
Does changing an element position inside an array recreate the entire array with new elements?
- If you use the array indexer
[]
, then no: the array is not recreated, it's mutated in-place. - If you use
Array.prototype.splice
, then no: the array is not recreated, it's mutated in-place.- But
splice
does return a new array containing the removed elements.
- But
- If you use
Array.prototype.filter
and/orArray.prototype.map
, then yes: a new array containing only the filtered elements is returned (and the original input array is unmodified at all: i.e. nothing is mutated). - If you use
Array.prototype.forEach
to assign elements back to itself (which you shouldn't be doing anyway), then no: the array is mutated in-place.
Imagining a specific case in JavaScript, for example:
let animals = ["monkey","zebra","banana","capybara"]; animals.splice(2,1); // returns ["banana"]
Would it be correct to state that the entire
animals
array was rewritten?
No. That would be incorrect.
The correct thing to say is that "the animals
array was mutated".
It's stated in Javascript documentation that the
.splice()
method "takes" an array object, creates a new array without it and returns another one with it as an output, but how does it work?
I don't know what "JavaScript documentation" you're referring to, but that is incorrect.
The only authoritative sources for JavaScript documentation are either the official ECMAScript specification or documentation provided by JavaScript engine vendors (such as Mozilla's Spidermonkey) documented on MDN.
Sources such as W3Schools are not authoritative.
...and MDN says this about splice
(emphasis mine):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
The
splice()
method changes the contents of an array by removing or replacing existing elements and/or adding new elements in place.
how does it work?
The inner-workings of the splice
function are defined in the ECMAScript specification (section 23.1.3.29).
...which can be summarized as:
- Given a
splice
invocation with arguments( this: Array, start: int, deleteCount: int );
... - Create a new array to hold
deleteCount
items:deletedItems
. - Copy elements in
this
from indexstart
tostart deleteCount
intodeletedItems
. - Copy elements in
this
fromstart deleteCount
tothis.length
upwards to fill the gap of removed items. - Shrink the
length
tothis.length - deleteCount
.
In TypeScript, something like this (ignoring handling of negative arguments):
function splice<T>( this: T[], start: int, deleteCount: int ): T[] {
const removedItems: T[] = [];
const tailIdx = start deleteCount;
for( let i = start; i < tailIdx; i ) {
removedItems.push( this[i] );
}
for( let i = tailIdx, f = start; i < this.length; i , f ) {
this[i] = this[f];
}
this.length = this.length - deleteCount;
}