58

这是我为这个简单任务编写的 javascript 代码:

  1. 如果元素存在于数组中,则删除该元素。
  2. 如果元素不在数组中,则添加该元素。

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

有没有更有效的方法来做到这一点?

4

8 回答 8

60

你可以在没有 3rd 方库的情况下做到这一点,这样会更有效率,就像这样。(如果找到,这只会删除值的第一个实例,而不是多个)

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);

输出

[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] 

jsfiddle 上

于 2013-06-17T17:36:09.017 回答
39

您可以使用 lodash 函数“xor”:

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

如果您没有数组作为第二个参数,您可以简单地将变量包装到数组中

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

这是文档:https ://lodash.com/docs/4.16.4#xor

于 2016-10-20T09:15:53.527 回答
33

对于不可变状态(克隆数组):

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

另请参阅: 从对象中删除属性 (JavaScript)

于 2018-07-17T20:46:46.747 回答
19

如果您关心效率,那么可能使用数组来实现集合是一个坏主意。例如使用你可以做的对象:

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

然后经过多次添加/删除操作后,您只能保留值为 1 的键

这样,每次添加/删除都是O(1),您只需要一次O(n)操作即可获得最终结果。

如果键都是“小”数字可能是位掩码甚至值得努力(未测试)

function toggle(S, x) {
    var i = x >> 4;
    S[i] = (S[i]|0) ^ (1<<(x&15));
}
于 2013-06-17T17:45:26.903 回答
5

看看这个类似问题的答案。

Lodash问题

罗达什要点

代码:

function toggle(collection, item) {
  var idx = collection.indexOf(item);
  if (idx !== -1) {
    collection.splice(idx, 1);
  } else {
    collection.push(item);
  }
}
于 2016-09-06T12:32:31.890 回答
3

如果“类型”可以是一个集合,那么

let toggle = type_id => this.types.delete(type_id) || this.types.add(type_id);
于 2019-03-19T20:20:16.673 回答
1

使用下划线

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

用法:

var a = [1,2,3];
var b = [4];
a = toggle(a,b); // [1,2,3,4]
a = toggle(a,b); // [1,2,3]
于 2014-12-27T15:39:20.327 回答
1

扩展Xotic750 的答案,这将始终确保切换的元素在数组中只出现一次。如果您的数组像用户输入一样有点随机,那么您可以这样做。

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());

于 2019-06-22T21:32:53.787 回答