只有在数组尚不存在的情况下才能将值推送到数组的最有效和最简洁的方法

时间:2014-05-30 08:58:49

标签: javascript lodash

假设一个名为myArray的数组包含多个值但没有重复 假设我想在它不会导致重复存在的情况下将值推入其中。 我如何确定重复项=>通过比较价值id

我考虑过Lodash#uniq来做这个伎俩:

myArray.push(aNewValue);
myArray = _.uniq(myArray,function(item){
   return item.id;
});

但是,我不喜欢重新分配阵列,特别是在检查前我必须推动... 是否有更多"功能"在非常短的时候实现它的方法?

我不想明确地遍历数组以便应用支票 这就是我尝试使用Lodash的原因。

3 个答案:

答案 0 :(得分:4)

您可以在添加项目之前检查其是否存在:

if(myArray.indexOf(aNewValue) == -1) {
    myArray.push(aNewValue);
}

答案 1 :(得分:2)

您可以使用Array.prototype.some()来确定该值是否已经是数组的一部分,例如:

if( myArray.some(function (elem) { return elem.id == newValue.id }) ) 
   myArray.push(newValue);

但是,如果没有循环遍历数组,你真的无法逃脱。

答案 2 :(得分:2)

执行此操作的最有效方法通常是将对象用于唯一性,因为对象最多只能有一个特定值的键。但是,这仅限于字符串和字符串化的东西,因为只有字符串可以是对象键。

这里有两种方法。如果你经常使用你的数组,那么你应该保持并行结构 - 一个唯一性检查的对象,一个数组的数组。

如果你不经常需要你的阵列,也就是说你想要推送一堆东西,然后让一个数组是独一无二的,你可以只使用该对象,并在需要时将其转换为数组(这有点贵,所以你只想做一次,但仍然比一直操纵两种不同的结构便宜。)

第一种方法如下所示:

function Set() {
  this.presence = {};
  this.array = [];
};
Set.prototype.push = function(key, value) {
  if (this.presence[key]) return;
  this.presence[key] = true;
  this.array.push(value);
};

var a = new Set();
a.push(3, { id: 3, value: "SOMETHING" });
a.push(7, { id: 7, value: "SOMETHING ELSE" });
a.push(3, { id: 3, value: "SOMETHING" });
console.log(a.array); // => only 2 elements

第二个,这里:

function Set() {
  this.store = {};
};
Set.prototype.push = function(key, value) {
  this.store[key] = value;
};
Set.prototype.array = function() {
  var that = this;
  return Object.keys(this.store).map(function(key) { return that.store[key]; })
};

...
console.log(a.array()); // note the newly added parentheses :)

这两个仍然比使用indexOf在数组中寻找存在更便宜,当你进行自己的迭代时更是如此,除非数组非常短,否则很多。