Reputation: 65
I'm currently making a small app to practice JavaScript
and jQuery
.
I have an array of fruits.
var fruits = [apples, bananas, grapes, watermelons, tomatoes];
And on a click event I want to remove tomatoes
but if I change my mind clicking the same button, it will add tomatoes
back to the array fruits
. I've been using splice
to remove but I don't know what to use to add the splice
element back into the array.
Edit for clarification:
The element is not necessary going to be tomatoes
, but it could be any random element in the fruits
array. I'm using
fruits.splice(i,1);
Upvotes: 1
Views: 12062
Reputation: 350365
To insert a value back into an array (at the same position) after you spliced it, can in general be done like this:
// delete:
var deleted = fruits.splice(i, 1);
// restore:
fruits.splice(i, 0, deleted);
Note that deleted
is an array with one element here.
It can also done by taking a kind of backup of the original array:
// backup
var backup = fruits.slice(); // copy
// delete:
fruits.splice(i, 1);
// restore:
fruits = backup;
To support multiple undo actions, you could use an undo stack, which would just keep track of all the versions of your array. When the user performs an undo-action, the previous version is popped from that stack. This way you can undo more than one removal:
var fruits = ['Apples', 'Bananas', 'Grapes', 'Watermelons', 'Tomatoes'];
var undoStack = [];
function showFruits() {
$('#fruits').html('').append(
// translate the array to a list of LI elements with delete buttons
fruits.map(function(fruit) {
return $('<li>').text(fruit).append(
$('<button>').addClass('delete').text('Delete'));
})
);
}
$(document).on('click', 'button.delete', function () {
undoStack.push(fruits.slice()); // save a copy of the current array on the stack
fruits.splice($(this).parent().index(), 1); // remove from array at index
showFruits(); // update display
});
$('#undo').click(function () {
if (!undoStack.length) return; // cannot undo
fruits = undoStack.pop(); // get previous state
showFruits(); // update display
});
showFruits(); // show initial list
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="fruits"></ul>
<button id="undo">Undo</button>
If you are troubled by the memory usage of storing the complete array each time you delete an element, you could use the following alternative functions, which will only store the index and deleted value at every delete action:
$(document).on('click', 'button.delete', function () {
var i = $(this).parent().index(); // get index where to delete
var deleted = fruits.splice(i, 1); // remove from array at that index
undoStack.push([i, deleted]); // save the index and value on the stack
showFruits(); // update display
});
$('#undo').click(function () {
if (!undoStack.length) return; // cannot undo
var restore = undoStack.pop(); // get information for re-inserting
fruits.splice(restore[0], 0, restore[1]); // insert the value
showFruits(); // update display
});
If you would use the undo principle also for other modifications, like undoing an insert, or a modification of the label, then the first solution would not need much modification, while the more memory-efficient one would need a bit more.
For a more generic and elaborated solution on undo/redo operations on any object (not only arrays), see How to version control an object?
Upvotes: 5
Reputation: 56753
If the array position does not matter:
fruits.push(tomatoes);
If you want to insert it at a specific position (index) in the array:
fruits.splice(index, 0, tomatoes);
will insert tomatoes
into fruits
at the specified index
(deleting 0
items first, so it's just an insert).
Array.prototype.splice()
The
splice()
method changes the content of an array by removing existing elements and/or adding new elements.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
var deletedFruits = fruits.splice(i,1);
will contain an array of the removed element(s) because that is the return value of splice()
. So
fruits = fruits.concat(deletedFruits);
will re-add the deleted fruits.
Store the position of the deleted element:
var deletedFruit = { fruit: fruits.splice(i,1)[0], index: i }
If need be you can restore deleted fruits at their original array position using the aforementioned
fruits.splice(deletedFruit.index, 0, deletedFruit.fruit);
Upvotes: 2
Reputation: 833
You can add and remove fruits with these two functions:
function addFruit(fruit) {
fruits.push(fruit);
}
function removeFruit(fruit) {
// indexOf method returns index of fruit in the list, or -1 if fruit is not found.
var index = fruits.indexOf(fruit);
if (index > -1) {
fruits.splice(index, 1);
}
}
This assumes you have already defined an array named fruits. Then you can do something like
<script>
function updateOutput() {
document.getElementById('output').innerHTML = fruits.join(', ');
}
function addSelectedFruit() {
var selectedFruit = document.getElementById('fruit-select').value;
addFruit(selectedFruit);
updateOutput();
}
function removeSelectedFruit() {
var selectedFruit = document.getElementById('fruit-select').value;
removeFruit(selectedFruit);
updateOutput();
}
</script>
<input type="text" id="fruit-select"/>
<button onclick="addSelectedFruit();">Add</button>
<button onclick="removeSelectedFruit();">Remove</button>
List of fruits:
<p id="output"></p>
Example:
<script>
var fruits = ['Apples', 'Pears', 'Pineapples'];
function addFruit(fruit) {
fruits.push(fruit);
}
function removeFruit(fruit) {
var i = fruits.indexOf(fruit);
if (i > -1) {fruits.splice(i, 1);}else{alert(fruit + ' cannot be removed, as it is not present in the array of fruits.');}
}
function selectedFruit() {
return document.getElementById('fruit-select').value;
}
function updateOutput() {
document.getElementById('output').innerHTML = fruits.join(', ');
}
</script>
Fruit:
<input type="text" id="fruit-select" value="Orange"/>
<button onclick="addFruit(selectedFruit());updateOutput();">Add</button>
<button onclick="removeFruit(selectedFruit());updateOutput();">Remove</button>
<p id="output">Apples, Pears, Pineapples</p>
Upvotes: 0