Deleting Array Elements in JavaScript - Delete VS Splice

Deleting array elements in JavaScript - delete vs splice

delete will delete the object property, but will not reindex the array or update its length. This makes it appears as if it is undefined:

> myArray = ['a', 'b', 'c', 'd']
["a", "b", "c", "d"]
> delete myArray[0]
true
> myArray[0]
undefined

Note that it is not in fact set to the value undefined, rather the property is removed from the array, making it appear undefined. The Chrome dev tools make this distinction clear by printing empty when logging the array.

> myArray[0]
undefined
> myArray
[empty, "b", "c", "d"]

myArray.splice(start, deleteCount) actually removes the element, reindexes the array, and changes its length.

> myArray = ['a', 'b', 'c', 'd']
["a", "b", "c", "d"]
> myArray.splice(0, 2)
["a", "b"]
> myArray
["c", "d"]

Why is splice deleting my entire array? I would only like to delete max if it is in position 0

splice does not return a modified copy of the array. The array is modified in-place, and what is returned is the deleted subarray, if any.

In effect, your code is:

const deletedElements = prices.splice(0, 1);
prices = deletedElements;

You deleted the first element from the array, then replaced that array with another array which only contains the first element. Thus, it is not that only the first element is returned, as you claim. splice is working exactly as documented.


Also, prices.splice(0, 1) is more legibly written as prices.shift().

Why is splice removing all the elements from an array?

I can see at least two problems here:

  1. there should not be [i] before .splice

  2. You are iterating the array with for loop and whithin that loop you want to modify the length of that array - it looks like a bad idea to me..
    Better take a list of items to remove and after that loop ...remove them (begining from the last) in another loop like this:

     var removalList = [];
    for(let i = 0; i < projectileArray.length; i++){
    projectileArray[i].update();
    if(
    projectileArray[i].x + projectileArray[i].radius < 0 ||
    projectileArray[i].x - projectileArray[i].radius >= width ||
    projectileArray[i].y + projectileArray[i].radius < 0 ||
    projectileArray[i].y - projectileArray[i].radius >= height
    ){
    removalList.push(i);
    }
    }

    for(let i=removalList.length; i>0; i--){
    projectileArray.splice( removalList[i-1], 1 );
    }

How can I remove a specific item from an array?

Find the index of the array element you want to remove using indexOf, and then remove that index with splice.

The splice() method changes the contents of an array by removing
existing elements and/or adding new elements.

const array = [2, 5, 9];

console.log(array);

const index = array.indexOf(5);
if (index > -1) { // only splice array when item is found
array.splice(index, 1); // 2nd parameter means remove one item only
}

// array = [2, 9]
console.log(array);

Delete vs splice on associative array

The terminology in js can be confusing at first, so lets straighten that out.

Yes, pretty much everything in js is an object. However, there are differences in the data types.

An array can be used like as associative array, but it's different than an object literal.

var x = []; //array
var y = {}; //object literal

An array is like a list. The keys of an array can be a numerical index or a string.

var x = ['a','b']; // x[0] === 'a', x[1] === 'b';
var x = [];
x['one'] = 'a';
x['blah'] = 'b';

Object literals are like dictionaries. They can be used in a similar way.

var x = { 0: 'a', 1: 'b' };
var x = { one: 'a', two: 'b' };

However, this is where you need to understand the differences.

You can use an array like an object literal, but you can't use an object literal quite like an array.

Arrays have the automated "length" property, that increments and decrements automatically based on the total number of elements in the array. You don't get this with object literals. Arrays also get all of the other array-specific methods like shift, unshift, splice, pop, push, etc. Object literals don't have those methods.

Let's talk about delete and what happens on an array and on an object literal.

var x = ['a', 'b']; //["a", "b"]
delete x[0]; //[undefined, "b"]

var x = {0:'1', 1:'b'}// { 0:"1", 1:"b"}
delete x[0]; // { 1:"b" }

If you perform a delete on an element of an array, the length of the array doesn't change. The element index is preserved and the value is set to 'undefined';

Conversely, performing a delete on an object literal removes the key/value from the object.

Finally, if you want to remove an element from an array.

var x = ['a', 'b']; 
x.splice(0,1); //modifies x. ['b']

So, in summary use delete on object literals. Use splice on arrays.

Hope this helps.

Array splice removing wrong item or multiple ones at once

What I would do is update the code to reference something unique in the data (like the id field you have). This isn't required but would be less error prone. I'd use a filter here so you don't have array mutation issues between state transitions.

this.setState( {cart: cart.filter( item => item.id !== deleteId )}

where deleteId is the id of the entity the user wishes to delete.

That would look something like this

{ cart.map(item =>
<CartItem
key={item.id}
data={item}
onDelete={this.deleteProduct}
/>
)}

assuming CartItem calls this.props.onDelete(this.props.data.id)

Remember to double check the method you are using to handle data changes like this. Array::splice mutates the array. Currently you are calling splice twice in the delete function which will remove elements in both calls.



Edit:

your function should look something like this

deleteProduct = async (deleteId) => {
this.setState({ loading: true, items: [] })
const cart = this.state.cart.filter( item => item.id !== deleteId )}
this.setState({ cart })
try {
await AsyncStorage.setItem('cart', JSON.stringify(cart))
this.setState({ loading: false })
this.retrieveCart()
} catch (error) {
this.setState({ error: error, loading: false })
console.log(error.message)
}
}

JavaScript `delete foo[1]` returns empty value

const output = document.getElementById('output');
const filepicker = document.getElementById('filepicker');
const addToArray = [];
const deleteFromArray = [];

filepicker.addEventListener('change', (event) => {
const files = event.target.files;
output.textContent = '';
for (const file of files) {
const li = document.createElement('li');
li.textContent = file.name;
output.appendChild(li);
}
})

document.getElementById("addArray").addEventListener("click", function() {
if (filepicker.files.length <= 0) {
alert('filepicker empty')
} else {
addToArray.length = 0;
for (var i = 0; i <= filepicker.files.length - 1; i++) {
var fname = filepicker.files.item(i).name;
addToArray.push(fname);
}
console.log(addToArray);
}
});

document.getElementById("arrayCount").addEventListener("click", function() {
if (filepicker.files.length <= 0) {
alert('filepicker empty')
} else {
console.log(`Array count: ${addToArray.length} \n New array: [${addToArray}]`);
}
});

document.getElementById("deleteArray").addEventListener("click", function() {
if (filepicker.files.length <= 0) {
alert('filepicker empty')
} else {
var deleteIndex = prompt("Enter index to delete (starts from 0):")
console.log(addToArray.splice(deleteIndex, 1));
}
});
<input type="file" id="filepicker" multiple>
<div>
<p>List of selected files:</p>
<ul id="output"></ul>
</div>
<div>
<button type="button" id="addArray">Add to array</button>
<button type="button" id="deleteArray">Delete from array</button>
<button type="button" id="arrayCount">Check array count</button>
</div>

Delete array element and shift the rest of it to the left

The method you're looking for is splice: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice

arr.splice(index, 1)

delete element from array without empty slots

You can use .splice() to delete the data like this:

test.splice(1,1);

Then the test.length with show 2 as the array length.

If you do not wish to reindex the array, you can simply use the .filter() method to filter the undefined data from your array like this:

var test = []

test.push({
bezeichnung: "test_1"
});
test.push({
bezeichnung: "test_2"
});
test.push({
bezeichnung: "test_3"
});

delete test[1];

console.log(test.length) //will log 3
console.log(test.filter(a=>a).length) //will log 2


Related Topics



Leave a reply



Submit