Deleting items from an array requires multiple passes to remove them all
That's you modifying underlying collection while iterating over it.
Basically, if collection changes in some way during iteration (becomes empty, gets prepended with a new element, etc), iterator doesn't have a lot of ways to handle it.
Try reject instead.
list.reject! {|item| item.name =~ /cat|dog|rat/i }
How to remove multiple items from a list in just one statement?
In Python, creating a new object e.g. with a list comprehension is often better than modifying an existing one:
item_list = ['item', 5, 'foo', 3.14, True]
item_list = [e for e in item_list if e not in ('item', 5)]
... which is equivalent to:item_list = ['item', 5, 'foo', 3.14, True]
new_list = []
for e in item_list:
if e not in ('item', 5):
new_list.append(e)
item_list = new_list
In case of a big list of filtered out values (here, ('item', 5)
is a small set of elements), using a set
is faster as the in
operation is O(1) time complexity on average. It's also a good idea to build the iterable you're removing first, so that you're not creating it on every iteration of the list comprehension:unwanted = {'item', 5}
item_list = [e for e in item_list if e not in unwanted]
A bloom filter is also a good solution if memory is not cheap. Function to delete an element from an array not working
The problem is rather silly:
At the beginning of deleteElement()
, you define i
with int i = 0;
, but you redefine another variable i
as a local index in each for
loop. The for
loop introduces a new scope, so the int i
definition in the first clause of the for
loop defines a new i
, that shadows the variable with the same name defined in an outer scope.
for (int i; i < length; i++) {
And you do not initialize this new i
variable.There are 2 consequences:
- undefined behavior in the first loop as
i
is uninitialized. The comparisoni < length
might fail right away. - the test
if (i == (length - 1)) {
tests the outeri
variable, not the one thatfor
iterated on. Furthermore, the test should beif (i == length) {
the nested
for
loop iterates once too many times: whenj == length - 1
, accessingarray[j + 1]
has undefined behavior.you do not update
length
, so the last element of the array is duplicated. You must passlength
by reference so it is updated in the caller's scope.
#include <iostream>
using namespace std;
void deleteElement(int array2[], int& length, int element);
int main() {
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, &length, 4);
cout << "\nIn main function\n";
for (int i = 0; i < length; i++) {
cout << array1[i] << " ";
}
return 0;
}
void deleteElement(int array2[], int& length, int element) {
int i;
for (i = 0; i < length; i++) {
if (array2[i] == element)
break;
}
if (i == length) {
cout << "Element doesn't exist\n";
} else {
length -= 1;
for (; i < length; i++) {
array2[i] = array2[i + 1];
}
}
cout << "Testing OP in deleteElement\n";
for (i = 0; i < length; i++) {
cout << array2[i] << " ";
}
}
How to delete an item from state array?
To remove an element from an array, just do:
array.splice(index, 1);
In your case:removePeople(e) {
var array = [...this.state.people]; // make a separate copy of the array
var index = array.indexOf(e.target.value)
if (index !== -1) {
array.splice(index, 1);
this.setState({people: array});
}
},
How can I remove a specific item from an array in JavaScript?
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);
Rails 3 - Remove items belonging to array B from array A
a = ["1","2","3","4","5","6"]
b = ["1","3"]
c = a - b
same asc = a.reject{ |e| b.include? e }
Remove all elements contained in another array
Use the Array.filter()
method:
myArray = myArray.filter( function( el ) {
return toRemove.indexOf( el ) < 0;
} );
Small improvement, as browser support for
Array.includes()
has increased:myArray = myArray.filter( function( el ) {
return !toRemove.includes( el );
} );
Next adaptation using arrow functions:
myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
How to remove item from array by value?
This can be a global function or a method of a custom object, if you aren't allowed to add to native prototypes. It removes all of the items from the array that match any of the arguments.
Array.prototype.remove = function() {
var what, a = arguments, L = a.length, ax;
while (L && this.length) {
what = a[--L];
while ((ax = this.indexOf(what)) !== -1) {
this.splice(ax, 1);
}
}
return this;
};
var ary = ['three', 'seven', 'eleven'];
ary.remove('seven');
/* returned value: (Array)
three,eleven
*/
To make it a global-function removeA(arr) {
var what, a = arguments, L = a.length, ax;
while (L > 1 && arr.length) {
what = a[--L];
while ((ax= arr.indexOf(what)) !== -1) {
arr.splice(ax, 1);
}
}
return arr;
}
var ary = ['three', 'seven', 'eleven'];
removeA(ary, 'seven');
/* returned value: (Array)
three,eleven
*/
And to take care of IE8 and below-if(!Array.prototype.indexOf) {
Array.prototype.indexOf = function(what, i) {
i = i || 0;
var L = this.length;
while (i < L) {
if(this[i] === what) return i;
++i;
}
return -1;
};
}
Remove an array element and shift the remaining ones
You just need to overwrite what you're deleting with the next value in the array, propagate that change, and then keep in mind where the new end is:
int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// delete 3 (index 2)
for (int i = 2; i < 8; ++i)
array[i] = array[i + 1]; // copy next element left
Now your array is {1, 2, 4, 5, 6, 7, 8, 9, 9}
. You cannot delete the extra 9
since this is a statically-sized array, you just have to ignore it. This can be done with std::copy
:std::copy(array + 3, // copy everything starting here
array + 9, // and ending here, not including it,
array + 2) // to this destination
In C++11, use can use std::move
(the algorithm overload, not the utility overload) instead.More generally, use std::remove
to remove elements matching a value:
// remove *all* 3's, return new ending (remaining elements unspecified)
auto arrayEnd = std::remove(std::begin(array), std::end(array), 3);
Even more generally, there is std::remove_if
.Note that the use of std::vector<int>
may be more appropriate here, as its a "true" dynamically-allocated resizing array. (In the sense that asking for its size()
reflects removed elements.)
remove objects from array by object property
I assume you used splice
something like this?
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
}
}
All you need to do to fix the bug is decrement i
for the next time around, then (and looping backwards is also an option):for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
To avoid linear-time deletions, you can write array elements you want to keep over the array:var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
and to avoid linear-time lookups in a modern runtime, you can use a hash set:const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
which can be wrapped up in a nice function:const filterInPlace = (array, predicate) => { let end = 0;
for (let i = 0; i < array.length; i++) { const obj = array[i];
if (predicate(obj)) { array[end++] = obj; } }
array.length = end;};
const toDelete = new Set(['abc', 'efg']);
const arrayOfObjects = [{id: 'abc', name: 'oh'}, {id: 'efg', name: 'em'}, {id: 'hij', name: 'ge'}];
filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));console.log(arrayOfObjects);
Related Topics
Remove Adjacent Identical Elements in a Ruby Array
What Is The Ruby Equivalent to This Curl Request
Do Ruby Objects Have a Size Limit
Binding to Networking Interfaces in Ruby
Fastest Way to Skip Lines While Parsing Files in Ruby
Rails How to Create Data Schema Seed Data
Command Not Found/Install Missing Gem Binaries with 'Bundle Install' Using Autotest
Many to Many Table with an Extra Column in Rails
Rails Validating Search Params
Dbi::Interfaceerror: Could Not Load Driver (Uninitialized Constant MySQL error)
What's The Best Way to Test Delayed_Job Chains with Rspec
Starting with Redmine Locally - How Easy Is Migration to Server Later
Accessing Microsoft Exchange Server from Ruby
I Am Getting This Gem Install Error for Kgio Gem When I Do a Bundle Install
How to Print a Multi-Dimensional Array in Ruby