push only unique elements in an array

2020-04-10 01:04发布

问题:

I have array object(x) that stores json (key,value) objects. I need to make sure that x only takes json object with unique key. Below, example 'id' is the key, so i don't want to store other json objects with 'item1' key.

x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]    

var clickId = // could be "item1", "item2"....
var found = $.inArray(clickId, x);  //
if(found >=0)
{
    x.splice(found,1);
}
else{
    x.push(new Item(clickId, obj)); //push json object
}

回答1:

would this accomplish what you're looking for? https://jsfiddle.net/gukv9arj/3/

x = [
    {"id":"item1","val":"Items"},
    {"id":"item1","val":"Items"},
    {"id":"item2","val":"Items"}
];    

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


回答2:

You can't use inArray() because you are searching for an object.

I'd recommend rewriting a custom find using Array.some() as follows.

var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}]    

var clickId = "item1";
var found = x.some(function(value) {
  return value.id === clickId;
});
alert(found);



回答3:

JS objects are great tools to use for tracking unique items. If you start with an empty object, you can incrementally add keys/values. If the object already has a key for a given item, you can set it to some known value that is use used to indicate a non-unique item.

You could then loop over the object and push the unique items to an array.

var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
    {"id":"item2","val":"bar"},
    {"id":"item1","val":"baz"},
    {"id":"item1","val":"bez"}];

for (var i = 0; i < x.length; i++) {
    var item = x[i];
    if (itemsObj[item.id]) {
        itemsObj[item.id] = "dupe";
    }
    else {
        itemsObj[item.id] = item;
    }
}

for (var myKey in itemsObj) {
    if (itemsObj[myKey] !== "dupe") {
        itemsList.push(itemsObj[myKey]);
    }
}

console.log(itemsList);

See a working example here: https://jsbin.com/qucuso

If you want a list of items that contain only the first instance of an id, you can do this:

var itemsObj = {};
var itemsList = [];
x = [{"id":"item1","val":"foo"},
    {"id":"item2","val":"bar"},
    {"id":"item1","val":"baz"},
    {"id":"item1","val":"bez"}];

for (var i = 0; i < x.length; i++) {
    var item = x[i];
    if (!itemsObj[item.id]) {
        itemsObj[item.id] = item;
        itemsList.push(item);
    }
}

console.log(itemsList);


回答4:

This is late but I did something like the following:

let MyArray = [];
MyArray._PushAndRejectDuplicate = function(el) {
    if (this.indexOf(el) == -1) this.push(el)
    else return;
} 

MyArray._PushAndRejectDuplicate(1); // [1]
MyArray._PushAndRejectDuplicate(2); // [1,2]
MyArray._PushAndRejectDuplicate(1); // [1,2]


回答5:

This is how I would do it in pure javascript.

var x = [{"id":"item1","val":"Items"},{"id":"item1","val":"Items"},{"id":"item1","val":"Items"}];

function unique(arr, comparator) {
  var uniqueArr = [];
  for (var i in arr) {
    var found = false;
    for (var j in uniqueArr) {
      if (comparator instanceof Function) {
        if (comparator.call(null, arr[i], uniqueArr[j])) {
          found = true;
          break;
        }
      } else {
        if (arr[i] == uniqueArr[j]) {
          found = true;
          break;
        }
      }
    }
    if (!found) {
      uniqueArr.push(arr[i]);
    }
  }
  return uniqueArr;
};

u = unique(x, function(a,b){ return a.id == b.id; });
console.log(u);

y = [ 1,1,2,3,4,5,5,6,1];
console.log(unique(y));