indexOf() The Array#indexOf() function is a common alternative to includes() . The indexOf() function returns the first index in the array at which it found valueToFind , or -1 otherwise.
Array.prototype.filter() The filter() method creates a shallow copy of a portion of a given array, filtered down to just the elements from the given array that pass the test implemented by the provided function.
T-SQL doesn't support arrays (groups of objects that have the same attributes and that you can use techniques such as subscripting to address individually). But you can use local or global temporary tables, which the main article describes, as an alternative to an array.
JavaScript Array filter() The filter() method creates a new array filled with elements that pass a test provided by a function. The filter() method does not execute the function for empty elements. The filter() method does not change the original array.
Is there an in-place alternative to filter
No, but it's not hard to write your own. Here is an approach which squeezes out all the values which fail a condition.
function filterInPlace(a, condition) {
let i = 0, j = 0;
while (i < a.length) {
const val = a[i];
if (condition(val, i, a)) a[j++] = val;
i++;
}
a.length = j;
return a;
}
condition
is designed to have the same signature as the callback passed to Array#filter
, namely (value, index, array)
. For complete compatibility with Array#filter
, you could also accept a fourth thisArg
parameter.
forEach
Using forEach
has the minor advantage that it will skip empty slots. This version:
thisArg
function filterInPlace(a, condition, thisArg) {
let j = 0;
a.forEach((e, i) => {
if (condition.call(thisArg, e, i, a)) {
if (i!==j) a[j] = e;
j++;
}
});
a.length = j;
return a;
}
a = [ 1,, 3 ];
document.write('<br>[',a,']');
filterInPlace(a, x=>true);
document.write('<br>[',a,'] compaction when nothing changed');
b = [ 1,,3,,5 ];
document.write('<br>[',b,']');
filterInPlace(b, x=>x!==5);
document.write('<br>[',b,'] with 5 removed');
You could use the following:
array.splice(0, array.length,...array.filter(/*YOUR FUNCTION HERE*/))
Explanation:
What you could use
Array#filter
returns an array with the same elements, but not necesserily all.Array#map
returns something for each loop, the result is an array with the same length as the source array.Array#forEach
returns nothing, but every element is processed, like above.Array#reduce
returns what ever you want.Array#some
/Array#every
returns a boolean value.But nothing from above is mutating the original array in question of length in situ.
I suggest to use a while loop, beginning from the last element and apply splice to the element, you want to remove.
This keeps the index valid and allows to decrement for every loop.
Example:
var array = [0, 1, 2, 3, 4, 5],
i = array.length;
while (i--) {
if (array[i] % 2) {
array.splice(i, 1);
}
}
console.log(array);
If you are able to add a third-party library, have a look at lodash.remove:
predicate = function(element) {
return element == "to remove"
}
lodash.remove(array, predicate)
The currently selected answer works perfectly fine. However, I wanted this function to be a part of the Array prototype.
Array.prototype.filterInPlace = function(condition, thisArg) {
let j = 0;
this.forEach((el, index) => {
if (condition.call(thisArg, el, index, this)) {
if (index !== j) {
this[j] = el;
}
j++;
}
})
this.length = j;
return this;
}
With this I can just call the function like so:
const arr = [1, 2, 3, 4];
arr.filterInPlace(x => x > 2);
// [1, 2]
I just keep this in a file called Array.js and require it when needed.
A slightly simplified TypeScript variant of user663031's answer:
function filter_in_place<T>(array: Array<T>, condition: (value: T) => boolean)
{
let next_place = 0;
for (let value of array)
{
if (condition(value))
array[next_place++] = value;
}
array.splice(next_place);
}
Using splice()
instead of setting the length
results in a 1.2x speedup for 1400000
iterations on Chrome 76.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With