Push()和惟一项

我有一个将唯一值推入数组的简单例子,它看起来像这样:

  this.items = [];


add(item) {
if(this.items.indexOf(item) > -1) {
this.items.push(item);
console.log(this.items);
}
}

看起来很直接,对吧?不,看起来是的。它不会添加任何值。我肯定这是我这边犯的某种愚蠢的错误,但我似乎找不到它。

195536 次浏览

You have to use === -1, if it equals to -1 i.e. item is not available in your array:

  this.items = [];


add(item) {
if(this.items.indexOf(item) === -1) {
this.items.push(item);
console.log(this.items);
}
}

Yep, it's a small mistake.

if(this.items.indexOf(item) === -1) {
this.items.push(item);
console.log(this.items);
}

Your logic is saying, "if this item exists already, then add it." It should be the opposite of that.

Change it to...

if (this.items.indexOf(item) == -1) {
this.items.push(item);
}

so not sure if this answers your question but the indexOf the items you are adding keep returning -1. Not to familiar with js but it appears the items do that because they are not in the array yet. I made a jsfiddle of a little modified code for you.

this.items = [];


add(1);
add(2);
add(3);


document.write("added items to array");
document.write("<br>");
function  add(item) {
//document.write(this.items.indexOf(item));
if(this.items.indexOf(item) <= -1) {


this.items.push(item);
//document.write("Hello World!");
}
}


document.write("array is : " + this.items);

https://jsfiddle.net/jmpalmisano/Lnommkbw/2/

I guess ES6 has set data structure, which you can use for unique entries

You can use the Set structure from ES6 to make your code faster and more readable:

// Create Set
this.items = new Set();


add(item) {
this.items.add(item);


// Set to array
console.log([...this.items]);
}

If you use Lodash, take a look at _.union function:

let items = [];
items = _.union([item], items)
var helper = {};
for(var i = 0; i < data.length; i++){
helper[data[i]] = 1; // Fill object
}
var result = Object.keys(helper); // Unique items

try .includes()

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

so something like

const array = [1, 3];
if (!array.includes(2))
array.push(2);

note the browser compatibility at the bottom of the page, however.

Push always unique value in array

ab = [
{"id":"1","val":"value1"},
{"id":"2","val":"value2"},
{"id":"3","val":"value3"}
];






var clickId = [];
var list = JSON.parse(ab);
$.each(list, function(index, value){
if(clickId.indexOf(value.id) < 0){
clickId.push(value.id);
}
});

Using Set

this.items = new Set();
this.items.add(1);
this.items.add(2);
this.items.add(1);
this.items.add(2);


console.log(Array.from(this.items)); // [1, 2]

In case if you are looking for one liner

For primitives

(this.items.indexOf(item) === -1) && this.items.push(item);

For objects

this.items.findIndex((item: ItemType) => item.var === checkValue) === -1 && this.items.push(item);

Simple use new Set() with concat. The most performant mostly and updated:

console.log([...new Set(["hey", "we", "have", "array"].concat(["hey", "we", "add", "these", "too", "but without second hey, we, have :)"]))])

If you want to add elements in a case insensitive way, please do this for arrays;i.e:

["hey", "we", "HaVe", "ArrAy"].filter(r => r !== '').map(r => r.toUpperCase())

This will check whether empty element:

.filter(r => r !== '')

Will check case insensitive:

.map(r => r.toUpperCase()

This can be achieved with single line of code.

this.items = this.items.includes(item) ? this.items : [...this.items, item];

Simple as possible!

  let items = [];
const addItem = (item) => {
items = [...new Set([...items, item])]
};