Home > front end >  Does any change in an array gets to change the entire array?
Does any change in an array gets to change the entire array?

Time:04-24

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.
  • If you use Array.prototype.filter and/or Array.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:

  1. Given a splice invocation with arguments ( this: Array, start: int, deleteCount: int );...
  2. Create a new array to hold deleteCount items: deletedItems.
  3. Copy elements in this from index start to start deleteCount into deletedItems.
  4. Copy elements in this from start deleteCount to this.length upwards to fill the gap of removed items.
  5. Shrink the length to this.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;
}
  • Related