I'm having an issue with removing items from a Javascript array. I am using a prompt, and when the user inputs a worker's ID number, I want that element to be removed from the array.
At the moment, my code will only remove the final element in the list.
This is my code:
var remove = function(){
var removeID = prompt("Enter ID of the worker you wish to remove: ");
var index = array.indexOf(removeID);
if(removeID == id){
array.splice(index, 1);
showArray();
}
else{
alert("id is not in the system");
}
}
You're mixing up array indices with elements. It should go like this:
var remove = function(){
var removeID = prompt("Enter ID of the worker you wish to remove: ");
var index = array.indexOf(removeID);
if(index > -1){ // HERE!!!
array.splice(index, 1);
showArray();
}
else{
alert("id is not in the system");
}
}
Two additional observations:
If IDs are numbers, then your call to array.indexOf() will always return -1. prompt() will always give you a string, not an integer; you should use parseInt() instead like this:
var removeID = parseInt(prompt("Enter ID of the worker you wish to remove: "));
Since IDs are meant to be unique, and depending on the context, it might make sense to store them inside an object rather than an array so that you don't risk having duplicate IDs.
I think you messed up your logic
if(removeID == id){
should probably be checking to see if the id exists in the array before removing it.
if(index !== -1){
and another guess since you did not give a runnable example:
var removeID = Number(prompt("Enter ID of the worker you wish to remove: "));
http://jsfiddle.net/dk4kb417/1/
This method should remove the index you want. It will ask for the element value. The first index of that value will be deleted:
var array = ['one','two','three',4,5,6,7,8,9,10];
var remove = function(removeID){
var index = array.indexOf(removeID);
if (index>-1) {
array.splice(index, 1);
}
}
remove(prompt("Enter ID of the worker you wish to remove: "));
console.log(array);
Related
I have a simple button that removes an item from a json object. This is currently working fine. The issue I have is that once it's clicked once it doesn't work again due to a js error. The error is reporting that an item is null.
I thought delete would remove the json item, not simply mark it as null.
See this JSFiddle
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if($(this).attr('id') == 'btn1') name = 'John2';
if($(this).attr('id') == 'btn2') name = 'Anna';
$.each(jsonObj, function(i, obj) {
if (obj.firstName == 'Anna') delete jsonObj[i];
});
$('div').text(JSON.stringify(jsonObj));
});
I need to get the json text from the div, remove an item from it, then save it as text back to the div. Any help would be appreciated.
you should be iterating over the .employees array element of the object
you can't delete an element from an array with delete - use .splice instead.
you should return false from the $.each callback once a match has been made, or you'll end up iterating over non-existent elements - you must always be careful when modifying the size of a collection whilst iterating over it.
See https://jsfiddle.net/alnitak/mjw4z7jL/1/
The reason is because you are removing items from the array while looping through the keys. When you remove an item, it will rearrange the other items depending on how the array is implemented internally, and you end up with a loop that doesn't iterate over the keys that you expect.
Use for loop instead of $.each or return false once you are inside the condition.
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if($(this).attr('id') == 'btn1') name = 'John2';
if($(this).attr('id') == 'btn2') name = 'Anna';
for(i=0; i < jsonObj.employees.length; i++){
if (jsonObj.employees[i].firstName == name){
jsonObj.employees.splice(i,1);
}
}
$('div').text(JSON.stringify(jsonObj));
});
https://jsfiddle.net/bipen/715qkhwo/4/
Remind you, this is not a proper solution and depends entirely on how your json object is. If there are two objects with same firstName, this might give you weird result. So make sure you add all of the needed condition before you delete it.
You were iterating through the root object, it has one single property, employees
You needed to loop through object.employees array
Far easier with native array filter function
Note: This will handle multiple Johns and Annas without issue
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if(this.id == 'btn1') name = 'John2';
else if(this.id == 'btn2') name = 'Anna';
else return;
jsonObj.employees = jsonObj.employees.filter(function(emp) {
return emp.firstName != name;
})
$('div').text(JSON.stringify(jsonObj));
});
https://jsfiddle.net/715qkhwo/5/
Seen this question a lot, but cannot find something that's what i'm looking for.
onClick I push an item to an array I have, however, if there's 3 items in my array I don't want to be able to push items anymore.
var selectedData = [];
I set my empty variable.
var index = selectedData.indexOf(3);
I then get the index of my array which is 3
if (index > 3) {
selectedData.splice(index, 1);
}
Then within my if statement I say, if my index which is 3, is bigger then 3, then splice at index and remove one.
selectedData.push(TheThing);
I then push TheThing to my array if the if statement above isn't true.
However, I have a variable var arrayLength = selectedData.length; that grabs the length, and when I console log it, it starts at 0 and splices items anything after 4. Not 3.
Any idea what i've done wrong or misunderstood?
Thanks
More full example of my code
var selectedData = [];
myElement.on('click', function() {
var index = selectedData.indexOf(3);
if (index > 3) {
selectedData.splice(index, 1);
}
var arrayLength = selectedData.length;
console.log(arrayLength, 'the length');
});
So in short, onClick check my array and remove anything after the third that gets added into my array.
Do you want this to behave as a stack or a queue?
So your code here:
var index = selectedData.indexOf(3);
Is not grabbing the 3rd index - its grabbing the first index where it sees 3, or -1 if it doesn't. Replace your if statement with,
if (selectedData.length > 3) {
selectedData.pop() // removes last element (stack)
// or
selectedData = selectedData.slice(1) //remove first element (queue)
}
I think you need to try var arrayLength = selectedData.length -1;
You start at 0 like a normal array, but don't you start with an empty array?
Plus when you use .length, it returns the true count of the array or collection not a 0 index.
`
you can override push() method of your array like this:
var a = [];
a.push = function(){}
or like this
a.push = function (newEl){
if(this.length <3){
Array.prototype.push.call(this, newEl)
}
}
This is not complete example because push() can take many arguments and you should to handle this case too
var index = selectedData.indexOf(3); simply give you the index of the element of the array that has value 3
Example
selectedData = [ 0, 3 , 2];
alert( selectedData.indexOf( 3 ) ); // this will alert "1" that is the index of the element with value "3"
you can use this scenario
var selectedData = [];
myElement.on('click', function() {
//if selectedData length is less than 3, push items
});
This could work.
myElement.on('click', function() {
if(selectedData.length > 3){
selectedData = selectedData.splice(0, 3);
}
console.log(selectedData.length, 'the length');
});
I'm facing a problem.
I have this:
<input type="hidden" name="Boss" id="Boss" value="8,116,167,198,139,203,158,170,">
Actually I have this code in js:
// On click on element with class .Boss
$("form").on("click", ".Boss", function(event){
var clickedId = $(this).attr('value')+','; // give me 8,
var locationBtn = $('#Boss'); // Select the input
var locationBtnValue = $('#Boss').val(); // Take the select value
if(locationBtnValue.toString().indexOf(clickedId) == -1) { locationBtn.val(locationBtnValue + clickedId); }
else { locationBtn.val(locationBtnValue.replace(clickedId,'')); }
});
My problem is: if want to decide to remove the 8 my javascript do not remove the item 8, but the first occurrence it will find in my string, so 8,116,167,19**8,**139,203,158,170,. So it breaks my other item...
How can I make to do not break it ?
Thanks.
I do not know what your final outcome is, but I think you want it to be 116,167,198,139,203,158,170, In this case you can split and filter the array to get rid of the value.
var str = "8,116,167,198,139,203,158,170,"; //the input
var updated = str.split(",") //turn it into an array
.filter(function (val) { //loop through all the elements applying this function
return val!=="8"; //keep the item if the index does not match the item
}
).join(","); //turn array back into a string
One way to be consistent is by splitting it into an array and then removing the occurence.
// On click on element with class .Boss
$("form").on("click", ".Boss", function(event) {
var clickedId = $(this).attr('value'); // give me 8
var locationBtn = $('#Boss'); // Select the input
var locationBtnValue = locationBtn.val(); // Take the select value
var ids = locationBtnValue.split(','); //split into an array
var index = ids.indexOf(clickedId); //index of clickedId inside ids
if(index > -1) { //found
ids = ids.splice(index, 1); //remove from ids
} else {
ids.push(clickedId); //add to ids
}
locationBtn.val(ids.join(','));
});
That's what replace does when you pass it a string, it replaces the first occurrence.
You need to pass it a regular expression with the global modifier, like this
locationBtnValue.replace(/8,/g,'')
you can do the same thing with the RegExp constructor, and create a regular expression from the string you have
var clickedId = $(this).val() + ',';
var regex = new RegExp(clickedId, "g");
locationBtnValue.replace(regex,'');
I'm trying to remove an object from an array by it's key/value of ID. I would normally just splice by index, however the index might be changing quite a bit because multiple users will be manipulating and updating the object so I want to hook onto something more concrete - aka the id. So I have a bit of logic to check if it still exists and if so remove it by it's ID. However I can't seem to get the syntax quite correct. I Am using underscore.js, I don't know if it's easier with/without it but it's worth mentioning.
Here's what I have -
$scope.toggleSelection = function(typeId,name,index){
//check if exists in array
check = $scope.multipleTypes.some( function( el ) {
return el.name === name;
});
//checked on/off actions
if($scope.items[index].checked == false || $scope.items[index].checked == undefined ){
//IS cecked
if(check){
//already exists, do nothing
}else{
$scope.multipleTypes.push({id:typeId, name:name, checked: true});
}
}else{
//IS not checked
if(check){
var list = _.filter($scope.multipleTypes, function(element){
return element.id != typeId;
}
$scope.multipleTypes = list;
}else{
//is not there, do nothing
}
}
};
So if it does exist and is checked off, it gets pushed. If it does exist and is unchecked, I want to remove it from $scope.multipleTypes by it's ID. I think I Am doing this wrong, all I want to do is remove that one object that has the matching ID from $scope.multipleTypes. Would appreciate any help. Thanks for reading!
If you can use UnderScore Js, You can do it very easily.
Here is an Example:
var someArray= [{Employee:'ved',id:20},
{Employee:"ved",age:25},
{Employee:"p",age:2}];
var a = _.findWhere(someArray,{id:25});//searching Element in Array
var b= _.indexOf(someArray,a);// getting index.
someArray.splice(b,1);// removing.
I normally find the object by id, then splice it out. Note that angularjs adds other properties to the object .
e.g
$scope.items = [......]
var findItemByID = function(id, items){
angular.forEach(items, function(item){
if(item.id === id){
return item;
}
})
return null;
}
var removeItemByID = function(id, items){
var item = findItemByID(id);
if(item){
items.splice(items.indexOf(item), 1);
}
}
//you can now do removeItemByID(id, $scope.items);
//I have not tested this code and it may have syntax errors. hope you get the idea.
Josh
I have an array that can look like this: ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"]
I want to access the element containing IN, if it exists and the next elements(s) until I reach and including an element with NN in it. and join those elements together into a string.
When I try to access the element containing IN like so, I get -1 that there is no element containing IN.
Here's how I am trying to do it:
strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
strARR[strARR.indexOf('IN')];
but then I get undefined because nothing at -1 exists.
How can I access the element of this array of strings if it contains IN and every element after until it matches an element containing NN, including that element? And joining those as a string?
You need a for loop for that:
var strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
var foundStr = null;
for (var i = 0, cString; i < strARR.length; ++i) {
cString = strARR[i];
if (cString.indexOf("IN") !== -1) {
foundStr = cString;
break;
}
}
if (foundStr !== null) {
/* do someting with found string */
}
strARR[strARR.indexOf('IN')] was returning a weird value because:
strARR.indexOf('IN') // returns -1 (no string "IN" in the array)
strArr[-1] // undefined
There is no "IN" element in that array. Just an "inIN" element, which is not precisely equal. (Keep in mind, this could be an array of ANYTHING, not just strings, so it's not assumed they can check the string contents)
You'll have to loop through the strARR, using a standard for(var i = 0; i < strARR.length; i++) loop. The i variable will help you find the correct indexes.
Then, for combining the results, use the Array.splice and Array.join methods. Splice can take a start index and length of items to take as arguments, and Join can take an intermediate character as an argument, like a comma, to put between them.
You need to evaluate each element in the array individually, not evaluate the array as a whole. Using jQuery each, you can do:
var containsIN = '';
$.each(strARR, function(){
if($(this).indexOf('IN') !== -1){
containsIN = $(this);
}
});
To achieve appending or joining string until you find a string that contains 'NN'
you need to modify the original if condition to:
if(containsIN === '' && $(this).indexOf('IN') !== -1)
then add another condition afterwards
if(containsIN !== ''){
final += $(this);
}
Then, to terminate the each:
if($(this).indexOf('NN') !== -1){
return false;
}
So, the final code should look like:
var containsIN = '';
var final = '';
$.each(strARR, function(){
if(containsIN === '' && $(this).indexOf('IN') !== -1){
containsIN = $(this);
}
if(containsIN !== ''){
final += $(this);
}
if($(this).indexOf('NN') !== -1){
return false;
}
});
You can use the Array's filter() function for this. There is a polyfill available on the linked page if you need to target browsers that do not support filter() natively.
You can create any filter condition that you like and filter() will return the array elements that match your condition.
var strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
var strARRFiltered = strARR.filter(function(element){
return element.indexOf("IN") !== -1;
});
alert(strARRFiltered);
Here is an example of this concept expanded a bit to include accessing multple matches and a variable filter.
To do what you're currently trying to do, the code would need to be like this:
strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
strARR[strARR.indexOf('inIN')];
You need to loop through each element in the array calling indexOf, rather than trying to access it as an array.