Apply function to a whole array except 1 element

Hi everybody,

This is my first post here :slight_smile: ! Today I am reaching out to you because I have a question about arrays in JavaScript.

But first, the context with my algorithm:

function fct1 (Array a, Element e, Boolean b) {
    // Some stuff here...

    if (b)
      fct2 (a);
      fct2 (a_modified);

    // Some more stuff here...

where a_modified is the Array a without the Element e.

Now, my modified array a_modified is used only once in the code and I can’t permanently modify a, so I can’t use methods like splice. I can’t modify fct2 either, so I really have to pass an array.

So I had 2 ideas here, but I am not so satisfied with them:

  1. Use a classical for loop to create another array stored in a variable. Basically you compare each value of the array with e and if it’s different you store it in the new array. Here I have to create a variable for something I will use only once, I know it’s not such a big deal but I’d like to avoid it if possible.

  2. Use the operations on arrays to locate the index of e, then concatenate the left and right part of the array. It would be something like that: a.slice(0, a.indexOf(e)).concat(a.slice(a.indexOf(i) + 1));. Frankly, this is just awful to read.

So here the for loop might be the best choice, but I was wondering if there wasn’t a way to make things easier. Like a “reversed slice” that would return everything except the sliced element. I know this sounds a bit stupid, but I am a beginner and I have absolutely no idea about the performance of JS Array object methods, nor a good vision of scopes between functions, and it makes me sort of curious :slight_smile: .

Thank you very much for your help!

Array.prototype.splice returns deleted elements. However, the best solution would be to look at that array and not include this rogue element you need fct2 for in the first place. Arrays should contain related items precisely to avoid situations like you’re running into. Are you in control of what this array contains?

The thing is, I will need this element somewhere else in fct1 later. And I don’t really have a control on its content, it’s an array containing all the elements of a scene (like furniture in a room). And I need to apply fct2 to all the elements of my room or all except one depending on the state of my Boolean.

Using the correct data structure is every bit as important as having a good algorithm, so if there’s any way to change that data to an object, you’d get much better results. But if you’re stuck with this as-is, then I wouldn’t modify the array at all and instead just ignore the element in the loop.

// ... in fct1()
for(var i = 0, length = a.length; i < length; i++) {
   if(b && a[i] = e) { continue; }
   // .. do stuff to every other element

Generally, you want to avoid modifying arrays. When you start changing the data that gets passed around, you can easily introduce bugs by having two (or more) different versions of that data. Also, it’s inefficient. Manipulating arrays is the easiest way to tank your application’s performance. Creating a new array is not so bad, but in your case completely avoidable.

But, assuming that for some reason it isn’t avoidable and you need a new array, look into Array.prototype.filter instead.

var newArray = oldArray.filter(function(item) { return item !== e; }); // creates a new array without the element e
1 Like