Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't arrays in Javascript resize when you remove an item? [duplicate]

In many languages, the standard dynamic list (not fixed-size array) type will resize after an item is deleted:

Python:

myList = ['a', 'b', 'c']
del(myList[0])
print(len(myList)) # Prints '2'

C#:

var myList = new List<string> {"a", "b", "c"};
myList.RemoveAt(0);
Console.WriteLine(myList.Count); // Prints '2'

and so on.

However, in Javascript, the list length stays the same, even though the element evaluates to undefined (this tells me that it's different to array[index] = undefined):

Javascript:

var myArray = ['a', 'b', 'c']
delete myArray[0]
console.log(myArray.length) // Prints '3'
console.log(myArray) // Prints "[ , 'b', 'c' ]" in node, '[undefined × 1, "b", "c"]' in Chrome

myArray[0] = undefined
console.log(myArray) // Prints "[ undefined, 'b', 'c' ]" on both node and Chrome

myArray.splice(0, 1)
console.log(myArray) // Prints "['b', 'c']"

My questions are:

  • Is the JS array delete behaviour by design or an oversight that couldn't be fixed for fear of breaking legacy code?
  • What exactly is the 'undefined-like' value that replaces the deleted array element?
like image 573
svbnet Avatar asked Feb 19 '17 10:02

svbnet


People also ask

Can we resize an array in JavaScript?

Once an array has been created, its size cannot be changed. Instead, an array can only be "resized" by creating a new array with the appropriate size and copying the elements from the existing array to the new one.

Are arrays able to change size as in grow or shrink length?

Arrays cannot expand or shrink. When the number of elements in the data structure exceeds the size of the backing array, a new array needs to be allocated and the data from the old array needs to be copied into the new array.

How do you shrink the size of an array?

The size of a Java array is fixed when you allocate it, and cannot be changed. If you want to "grow" or "shrink" an existing array, you have to allocate a new array of the appropriate size and copy the array elements; e.g. using System.

How do I remove an item from an array?

If you want to remove an item from an array, you can use the pop() method to remove the last element or the shift() method to remove the first element.


2 Answers

Your comparison of delete to RemoveAt and such is incorrect. delete doesn't do what they do; to do that, you'd use splice:

var myArray = ['a', 'b', 'c']
myArray.splice(0, 1);
console.log(myArray.length) // Prints '2'

delete removes the entry without reordering other entries, creating a sparse array (an array with some entries missing entirely). delete isn't really meant for arrays, it's meant for removing properties from objects; but it applies to arrays because standard (e.g., non-typed) arrays in JavaScript aren't really arrays at all*, they're objects with special handling for certain properties, such as those whose names are "array indexes" (which are defined as string names "...whose numeric value i is in the range +0 ≤ i < 2^32-1") and length.

length's value is changed if you:

  • Use any method to add or remove entries (splice, push, etc.).
  • Add an entry by assigning to an index equal to or greater than length.
  • Assign directly to length: If you increase length, you make the array sparse; if you decrease it, you remove any entries at that index or above. E.g., if you have an array ['a', 'b', 'c', 'd', 'e'] and do theArray.length = 3, it won't have entries at indexes 3 ('d') or 4 ('e') anymore.

Is the JS array delete behaviour by design or an oversight that couldn't be fixed for fear of breaking legacy code?

By design. As mentioned above, delete is primarily about removing properties from objects.

What exactly is the 'undefined-like' value that replaces the deleted array element

There isn't one. This is another by-product of the fact standard arrays are objects: If you try to read the value of a property from an object that it doesn't have, the result of that "get" operation is the value undefined. It's not that there's something in the object with an undefined-like value, it's that there's no property in that object with that name at all. This illustration may be useful:

var o = {}; // A non-array object
console.log(o.noSuchProperty);    // undefined
console.log(o["noSuchProperty"]); // undefined
console.log(o[2]);                // undefined

var a = []; // An array object
console.log(a.noSuchProperty);    // undefined
console.log(a["noSuchProperty"]); // undefined
console.log(a[2]);                // undefined

* (that's a post on my anemic little blog)

like image 103
T.J. Crowder Avatar answered Oct 10 '22 11:10

T.J. Crowder


This seems to be a duplicate of: deleting-array-elements-in-javascript-delete-vs-splice

As you mentioned using delete will not remove the element, but instead just set it to undefined. Splice, unshift or pop however, will remove that block from the array.

like image 20
CWright Avatar answered Oct 10 '22 11:10

CWright