Remove item from array using foreach - JavaScript [duplicate] - javascript

This question already has answers here:
How do I remove an element in a list, using forEach?
(5 answers)
Closed 7 years ago.
Is it possible to remove something from an array using foreach?
var array = [1,2,3,4,5,6,7,8];
array.forEach(function(data){
if (data == 4) {
// do something here
}
});
console.log(array);

I would advise against using the forEach function. It affects the iterator and skips the next item. Better: use a reverse for loop and remove the item by index.
var array = [1,2,3,4,5,6,7,8];
for (var i = array.length - 1; i > -1; i--) {
if (array[i] == 4) {
array.splice(i, 1);
}
}
Fiddle: https://jsfiddle.net/uu94y8Lx/

I would not recommend this. The forEach function iterates over the array and when you remove the current or a previous item it will skip the next item in the array. That being said if you really want to remove an item despite the problems you will run into it is possible to remove an item with array.splice(data, 1).

Try like this:
array.forEach(function(data){
if (data == 4){
console.log('done')
array.splice(data, 1);
}
});
Also as commented by mario its not recommended to modify the array you're looping on, so you can do like this:
var array1 = [];
array.forEach(function(data){
if(array.length === 4){
array1.push(data);
}
});
Also you can use the for loop like this:
var array = [1,2,3,4,5,6,7,8],i;
for (i = 0; i < array.length; ++i) {
if (array[i] === 4) {
array.splice(i--, 1);
}
}
console.log(array);

Related

Why does the last element of my array return undefined, rather than splicing it off? [duplicate]

This question already has answers here:
Looping through array and removing items, without breaking for loop
(17 answers)
Closed 5 years ago.
I'm working on a small exercise:
The problem is that I want this:
=> ['kept','kept']
But instead, I keep getting this:
function keep(array, keeper) {
//This will return an array of undefined's and 'kept's
// =>[ 'kept', undefined, 'kept', undefined, undefined ]
matchingNumbers = array.map(function matching(element){
if (element === keeper) {
return element;
}
});
//Eliminate all undefined's from the matchingNumbers array
matchingLength = matchingNumbers.length;
for (var i = 1; i < matchingLength; i++) {
if(matchingNumbers[i] === undefined) {
(matchingNumbers.splice(i, 1));
}
}
return matchingNumbers;
}
keep(['kept', 'thirty', 'kept', 2, 1], 'kept')
I'm trying to splice off all of the undefined's in matchingNumbers with the for-loop, so why is there a last undefined remaining?
When a function doesn't execute a return statement, it returns undefined by default. array.map() puts the return values of the function into the resulting array, and this includes those undefined values.
You should use array.filter instead of array.map:
matchingNumbers = array.filter(function matching(element){
return element === keeper;
});
My guess is because you're starting i at 1 instead of 0. Also, as #Wali mentioned, you're changing the array length while iterating over it. To solve that, go through the array in reverse order:
for (var i = array.length; i > 0; i--) {
...
}
As a side note, you can achieve what you want using Array.filter rather than dealing with mapping and splicing.

How to remove both instances of duplicated objects in an array

I have an array of objects. I am trying to find duplicated objects and then remove both instances of that object.
Right now I am using this method:
function checkForDups(data){
for(var i = 0; i < data.length; i++){
for(var j = i+1; j < data.length; j++){
if(data[j].number === data[i].number){
data.splice(j,1);
data.splice(i,1);
}
}
}
return data;
}
I believe problem is that it only checks for duplicates that have an index that greater than the current position it is checking. This means objects that are "behind" it in the array are not checked for duplication. Currently I run the array through this function a few times to get the desired results. However, this is obviously extremely inefficient. How could I achieve my desired results more efficiently?
I believe problem is that it only checks for duplicates that have an index that greater than the current position it is checking. This means objects that are "behind" it in the array are not checked for duplication.
No, that's a simply optimisation, made possible by the symmetry of the equality relation. By searching ahead and removing all duplicates in front of you, any current item can't be a duplicate of a previous one or it would have been already eliminated.
However, there are some things you did not take care of:
When splicing (removing) an item from the array, all subsequent ones are moved, and the array changes its length. To really examine all items in the array, you need decrease (or: not increase) the counter variable when removing, so that the new item which is now in the same spot as the removed one gets visited (the spot from which you just removed needs to get revisited).
You probably want to break the inner loop after having found a duplicate, otherwise you compare and remove totally different items.
You have not made clear what the algorithm should do when there are more than 2 duplicate items of the same sort in the array. Leave one when their number is odd? Thanks for your comment.
To remove all existing duplicates, you will need to continue the search, but must not remove the ith element immediately or you won't have anything to compare to furtheron - or you might even remove the ith item multiple times (see #2).
So this modification should fit:
function removeAllDups(data) {
// leaves only items in the array that appeared a single time
// removes everything whose .number can be found multiple times
for (var i = 0; i < data.length; i++) {
var found = false,
num = data[i].number;
for (var j = i+1; j < data.length; j++) {
if (data[j].number === num) {
found = true;
data.splice(j--, 1);
}
}
if (found) {
data.splice(i--, 1);
}
}
return data;
}
Here's an alternate implementation. This uses only two passes through the array, and removes all dupes in cases > 2: http://jsfiddle.net/nrabinowitz/1pdr780j/
function removeDupes(arr, test) {
test = test || function(a, b) { return a === b; };
function find(cache, element) {
return cache.some(test.bind(null, element));
}
var seen = [];
var dupes = [];
var len = arr.length;
var x;
var current;
// First pass - find dupes
for (x = 0; x < len; x++) {
current = arr[x];
if (find(seen, current)) {
dupes.push(current);
} else {
seen.push(current);
}
}
// Second pass: remove dupes. Reverse iteration saves headaches here
for (x = len - 1; x >= 0; x--) {
current = arr[x];
if (find(dupes, current)) {
arr.splice(x, 1);
}
}
}
This is an updated version that takes an optional test function to determine equality for dupe purposes; for the OP's case, the call would be
removeDupes(arr, function(a, b) {
return a.number == b.number;
});
Note that this assumes support for ES5 methods - Array#some, Function#bind. If you need to support older browsers, an ES5 shim or the Underscore library would fit the bill.
You could use underscore.js:
function checkForDups(data) {
return (
_.map(
_.filter(
_.pairs(
_.countBy(data)
), function(v) {return v[1] == 1}
), function(v) {return ~~v[0]}
)
)
}
Example
>> console.log(checkForDups([0,1,2,3,0,1,0,4]))
[2, 3, 4]
You can try it here.

removing elements from an array from another array in javascript [duplicate]

This question already has answers here:
How to get the difference between two arrays in JavaScript?
(84 answers)
Closed 8 years ago.
Hi i need to remove the array from another array.Below is the code that i had tried
var dummyObj = ["item1"];
var dummyArray = [ "item1", "item3", "item2"];
var data1=removeFromArray(dummyArray, dummyObj);
console.log("data1"+data1)
function removeFromArray(array, item)
{
while((index = array.indexOf(item)) > -1)
array.splice(index,1);
return array
}
below is my output
item1,item3,item2
But the required output is
item3,item2
Dont know where i am going wrong.Any help regarding this will be much helpful
You argument item is an is an array object so you have to use it like item[0]
while((index = array.indexOf(item[0])) > -1)
if dummyObj contains for than one values then you have to add an extra loop
function removeFromArray(array, item)
{
for(var j=0;j<item.length;j++){
while((index = array.indexOf(item[j])) > -1)
array.splice(index,1);
}
return array
}
The problem with your code is that, item is actually dummyObj which is an array and that does not exist in dummyArray. That is why it fails to remove it.
You can use Array.prototype.filter, like this
dummyArray = dummyArray.filter(function(currentItem) {
return dummyObj.indexOf(currentItem) === -1;
});
console.log(dummyArray); // [ 'item3', 'item2' ]
Check out Underscore.js, a javascript utility belt:
http://underscorejs.org/#difference
You have few errors there:
while((index = array.indexOf(item)) > -1)
Should be
while((index = array.indexOf(item) > -1)
Also you need to loop through both dummyArray and dummyObj, because your item variable is actually dummyObj, so you need to loop through it to check each element separately.

Filtering a JavaScript array [duplicate]

This question already has an answer here:
How to filter a javascript object array with variable parameters
(1 answer)
Closed 9 years ago.
I am looking for a way to filter my JavaScript Array() columns where the parentId is equal to a variable passed into the method.
// Array decleration
var columns = []; // Columns
//...
for (var i1 in columns) {
if (columns[i1].parentId == listItem) {
//...
Could anybody recommend the easiest way to filter this using either plain JavaScript or jQuery to avoid using the if statement as shown above?
var filteredColumns = columns.filter(function(column) {
return column.parentId == listItem;
});
array = [1,2,3,4,5];
result = $.grep(array, function(n,i) {
return n > 3;
});
This will return an array of filtered elements where the results are greater than 3. Here n is the element in consideration, and i the index of the element. So as per your requirement, the code can run like this:
resultArray = $.grep(columns,function(n,i) {
return n == parentId;
});
Use ES5 Array's filter method:
var filtered = columns.filter(function (item) {
return item.parentId === listItem
});
In the link above there is also a shim for old browsers.
You can also doing that manually:
var filtered = [];
for (var i = 0, item; item = columns[i++];)
if (item.parentId === listItem) filtered.push(item);
Don't use for…in to iterate over Array.

Delete from array in javascript

3 hours ago, I asked a question in SO , about deleting a part of an object, so I linked this question to it:
delete a part of object in javascript
but now another problem occurred when I deleted from that array.
I use that object to populate a FlexiGrid. but when I delete an item from that object by following code, instead of delete that item , it sets to undefined :( and flexigrid did not accept it for input data.
for (var i = 0; i < Roomdata.length; i++) {
if(Roomdata[i].id = X) {
delete Roomdata[i];
break;
}
}
For example, imagine I have 3 items in Roomdata like this :
{item1, item2, item3}
When I call this code to delete item2 , Roomdata object looks like this :
{item1, undefined, item3}
and this is a bad format to be accepted by flexigrid as input data
Is there any solution ?
Thanks every body and sorry about my bad syntax (I am new in English)
regards , Foroughi
Walk through the array in reverse order, and use .splice to remove the element.
You have to walk in the reverse order, because otherwise you end up skipping elements See below.
for (var i = Roomdata.length-1; i >= 0; i--) {
if (Roomdata[i].id == X) {
Roomdata.splice(i, 1);
break;
}
}
What happens if you don't walk in the reverse order:
// This happens in a for(;;) loop:
// Variable init:
var array = [1, 2, 3];
var i = 0;
array.splice(i, 1); // array = [2, 3] array.length = 2
// i < 2, so continue
i++; // i = 1
array.splice(i, 1); // i=1, so removes item at place 1: array = [2]
// i < 1 is false, so stop.
// array = [2]. You have skipped one element.
What you have is an Array. You should use the splice() method to remove an element from an array, not by deleteing the element.
for (var i = 0; i < Roomdata.length; i++) {
if(Roomdata[i].id = X) {
Roomdata.splice(i, 1);
break;
}
}
Using splice in spite of delete.
Roomdata.splice(i, 0);
splice attribute removes blank string elements, undefined references, NULLs and FALSEs.
it will solve your problem
To remove all of the elements of an array matching a particular value, you can do this:
// Remove all elements in arr[] matching val
for (let i = 0; i < arr.length; i++) {
if (arr[i] === val) {
arr.splice(i--, 1); // Remove arr[i] and adjust the loop index
}
}
Note that this is a forward scan of the array. The decrement of the loop index is necessary so that the loop does not skip the next element after an element is removed.

Categories

Resources