nns
nns

Reputation: 61

Alternative to array.splice in JavaScript

I am currently working on a project where I store numeric values in a JS array. After some changes it should be removed again. I currently use the array.splice method like this:

function removeA(arr, element) {
    var index = arr.indexOf(element);
    if (index >= 0) {
        arr.splice(index, 1 );
    }
    return arr;
} 

But this seems to give me issues on Safari. This piece of code works in every browser, like Chrome, Firefox, Opera. But not on Safari. It even works in the Technical Preview of Safari.

Does anyone have an alternative?

Thanks in advance :)

Upvotes: 5

Views: 22364

Answers (6)

Ori Drori
Ori Drori

Reputation: 191986

The best option is to use Array.prototype.toSpliced(), which is part of ES2023, and currently not supported by Firefox. It has the same api of Array.prototype.splice(), but it returns a new array, and doesn't mutate the original.

var arr = [0, 1, 2, 3, 4, 5, 6, 7];
var index = 5;

var result = arr.toSpliced(index, 1);

console.log(result);

You have to slice before and after the index, and concat the results. Note that Array.prototype.slice() doesn't mutate the original array like Array.prototype.splice() does.

var arr = [0, 1, 2, 3, 4, 5, 6, 7];
var index = 5;

var result = arr.slice(0, index).concat(arr.slice(index + 1));

console.log(result);

Or using ES6 and array spread:

var arr = [0, 1, 2, 3, 4, 5, 6, 7];
var index = 5;

var result = [...arr.slice(0, index), ...arr.slice(index + 1)];

console.log(result);

Upvotes: 14

Exodus 4D
Exodus 4D

Reputation: 2822

Some more ideas:

Option A flatMap():

Return an empty [] in order to "filter" elements. Less efficient but might be useful in case you want to add new elements as well.

const a = [3, 4, 5, 6];
const filter = 2;
const r = a.flatMap((v, j) => j !== filter ? v : []);
console.log(`Result: %o`, r);   // Result: [3, 4, 6]

Example for filter + insert

const a = [3, 4, 5, 6];
const filter = 2;
const insert = 1;
const value = 4.5;
const r = a.flatMap((v, j) => {
  if (j === filter) return [];
  if (j === insert) return [v, value];
  return v;
});
console.log(`Result: %o`, r);   // Result: [3, 4, 4.5, 6]


Option B Array.from():

const a = [3, 4, 5, 6];
const filter = 2;
const r = Array.from({length: a.length -1}, (_, i) => a[i >= filter ? i + 1: i]);
console.log(`Result: %o`, r);   // Result: [3, 4, 6]


Option C "Destructure":

const a = [3, 4, 5, 6];
const filter = 2;
const {[filter]: _, ...o} = a;
const r = Object.values(o);
console.log(`Result: %o`, r);   // Result: [3, 4, 6]

Upvotes: 0

Manav Akela
Manav Akela

Reputation: 174

Sorry for late but hopefully it is useful for someone else

var arr = [32, 33, 16, 40, 55, 2, 41, 3, 10];

document.write("Array : "+arr);
document.write("<br>");
document.write("Removed Elements : "+mySplice(arr,2,2));
document.write("<br>");
document.write("Processed Array : "+arr);


function mySplice(array,index,count) {
  var fixIndex = -1;
  var ret = [];
  arr = array.filter(function(element) {
    fixIndex++;
    if((fixIndex >= index && fixIndex < (index+count))) {
        ret[ret.length]=element;
        return false;
    } else {
        return true;
    }
  });
  return ret;
}

Or you can use simple version (NOTE: it is simple but reversed)

var arr = [32, 33, 16, 40, 55, 2, 41, 3, 10];
document.write("Array : "+arr);
document.write("<br>");
document.write("Processed Array : "+mySplice_simple(arr,2,2));


function mySplice_simple(arr,index,count) {
  fixIndex = -1;
  return arr.filter(function(i) {
    fixIndex++;
    return !(fixIndex >= index && fixIndex < (index+count));
  });
}

Or if you have to remove just one element then use this

var arr = [32, 33, 16, 40, 55, 2, 41, 3, 10];
document.write("Array : "+arr);
document.write("<br>");
document.write("Processed Array : "+mySplice_simple_v2(arr,2));


function mySplice_simple_v2(arr,index,count) {
  fixIndex = -1;
  return arr.filter(function(i) {
    fixIndex++;
    return fixIndex != index;
  });
}

Upvotes: 0

Haritsinh Gohil
Haritsinh Gohil

Reputation: 6272

Another Alternative to array.splice in JavaScript is array.reduce

var arr =[1,2,3,2,4,5,6,2];
var newarr = arr.reduce((acc, elem) => elem !== 2 ? acc.concat(elem) : acc, []);
console.log(newarr);

Upvotes: 1

kevin ternet
kevin ternet

Reputation: 4612

You can use the built-in filter()

var array = [1,2,3,7,4,5,6,7,12,54,7,691];
var array = array.filter(x => x !== 7);
console.log(array);

Upvotes: 8

Suren Srapyan
Suren Srapyan

Reputation: 68665

Try the slice() method

arr = arr.slice(index, 1 );

Upvotes: 0

Related Questions