20

I want to have a simple array of values, ie

var simpleArray = ["SE1","SE2","SE3"];

I want to check this array when an action happens (a click on a google map layer), that will pass a value to this function and either add the value to the array, or remove it from the array if it already exists.

I am now just a bit confused having seen .splice/push/inArray/indexOf (that doesn't work in IE)/grep (jQuery) - not sure what the best practice is.

JPMox
  • 593
  • 1
  • 6
  • 16

4 Answers4

36

Assuming the order of the items doesn't matter you can do something like this:

function toggleArrayItem(a, v) {
    var i = a.indexOf(v);
    if (i === -1)
        a.push(v);
    else
        a.splice(i,1);
}

The .indexOf() method does work in IE from version 9 onwards, but if you need to support older IE versions you can use a shim as explained at MDN. Or if you're using jQuery anyway use $.inArray() instead.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
7

my ES* variant

const toggleArrayValue = (arrayList, arrayValue) =>
  arrayList.includes(arrayValue)
    ? arrayList.filter(el => el !== arrayValue)
    : [...arrayList, arrayValue]
Denis Rudov
  • 833
  • 8
  • 16
6

extremely compact lodash version, using xor function, which is used to create a new array of values found only in one array and not the other

xor(array, [valueYouWantToToggle])
ehab
  • 7,162
  • 1
  • 25
  • 30
1

Also if the value is an object:

const eq = (a, b) => a == b

const toggle = (arr, item) => {
  const resultArray = [];
  let duplicate = false;
  for(let i = 0; i < arr.length; i++) {
    if(!eq(arr[i], item)) {
      resultArray.push(arr[i]);
    } else {
      duplicate = true
    }
  }
  if(!duplicate) {
    resultArray.push(item)
  }
  return resultArray;
}