How to toggle an element in array using JavaScript?

JavascriptArraysunderscore.jsToggle

Javascript Problem Overview


Here is my code for javascript for this simple task:

  1. Remove the element if it exists in an array.

  2. Add the element if it is not in an array.

     if(_.contains(this.types,type_id)){
     	var index = this.types.indexOf(type_id);
     	this.types.splice(index,1);
     }
     else{
     	this.types.push(type_id);
     }
    

Is there a more efficient way to do this?

Javascript Solutions


Solution 1 - Javascript

You could do it without a 3rd party library, this would be more efficient, like this. (this only removes the first instance of a value if found, not multiple)

Javascript

var a = [0, 1, 2, 3, 4, 6, 7, 8, 9],
    b = 5,
    c = 6;

function addOrRemove(array, value) {
    var index = array.indexOf(value);
    
    if (index === -1) {
        array.push(value);
    } else {
        array.splice(index, 1);
    }
}

console.log(a);

addOrRemove(a, b);
console.log(a);

addOrRemove(a, c);
console.log(a);

Output

[0, 1, 2, 3, 4, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 6, 7, 8, 9, 5]
[0, 1, 2, 3, 4, 7, 8, 9, 5] 

On jsfiddle

Solution 2 - Javascript

You can use the lodash function "xor":

_.xor([2, 1], [2, 3]);
// => [1, 3]

If you don't have an array as 2nd parameter you can simpy wrap the variable into an array

var variableToInsertOrRemove = 2;
_.xor([2, 1], [variableToInsertOrRemove]);
// => [1]
_.xor([1, 3], [variableToInsertOrRemove]);
// => [1, 2, 3]

Here's the doc: https://lodash.com/docs/4.16.4#xor

Solution 3 - Javascript

For immutable state ( clone array ):

const addOrRemove = (arr, item) => arr.includes(item) ? arr.filter(i => i !== item) : [ ...arr, item ];

see also: https://stackoverflow.com/questions/208105/remove-properties-from-objects-javascript/56030135#56030135

Solution 4 - Javascript

If you care about efficiency then may be using an array to implement a set is a bad idea. For example using an object you could do:

function toggle(S, x) {
    S[x] = 1 - (S[x]|0);
}

then after many add/remove operations you can keep only keys where the value is 1

This way every addition/removal is O(1) and you need only one O(n) operation to get the final result.

If keys are all "small" numbers may be a bitmask is even worth the effort (not tested)

function toggle(S, x) {
    var i = x >> 4;
    S[i] = (S[i]|0) ^ (1<<(x&15));
}

Solution 5 - Javascript

Look at this answer of similar question.

Lodash issue

Lodash gist

Code:

function toggle(collection, item) {
  var idx = collection.indexOf(item);
  if (idx !== -1) {
    collection.splice(idx, 1);
  } else {
    collection.push(item);
  }
}

Solution 6 - Javascript

If "types" can be a Set then

let toggle = type_id => this.types.delete(type_id) || this.types.add(type_id);

Solution 7 - Javascript

Using underscorejs

function toggle(a,b)
{
return _.indexOf(a,b)==-1?_.union(a,[b]):_.without(a,b);
}

Usage:

var a = [1,2,3];
var b = [4];
a = toggle(a,b); // [1,2,3,4]
a = toggle(a,b); // [1,2,3]

Solution 8 - Javascript

Extending Xotic750's answer this will always ensure that toggled elements occur only once in array. You this if your arrays are bit random like user inputs.

function toggleValueInArray(array, value) {
  var index = array.indexOf(value);

  if (index == -1) {
    array.push(value);
  } else {
    do {
      array.splice(index, 1);
      index = array.indexOf(value);
    } while (index != -1);
  }
}


var a = [0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9],
  b = 5,
  c = 10;

// toString just for good output
console.log(a.toString());

toggleValueInArray(a, b);
console.log(a.toString());

toggleValueInArray(a, c);
console.log(a.toString());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionwwliView Question on Stackoverflow
Solution 1 - JavascriptXotic750View Answer on Stackoverflow
Solution 2 - JavascriptDavid GinanniView Answer on Stackoverflow
Solution 3 - JavascriptYairTawilView Answer on Stackoverflow
Solution 4 - Javascript6502View Answer on Stackoverflow
Solution 5 - JavascriptWebBrotherView Answer on Stackoverflow
Solution 6 - JavascriptncluView Answer on Stackoverflow
Solution 7 - JavascriptFlavien VolkenView Answer on Stackoverflow
Solution 8 - JavascriptAbhay Raj SinghView Answer on Stackoverflow