简体   繁体   中英

Javascript : Objects with unique key within an array

I have an array of objects in this form :

[
  { id:"123", url:"example1.com"},
  { id:"123", url:"example2.com"},
  { id:"456", url:"example3.com"},
  { id:"789", url:"example4.com"},
]

I'm looking for a fast performing way to filter this array to keep only objects with a unique id, in this case, the output should be :

[
  { id:"123", url:"example1.com"},
  { id:"456", url:"example3.com"},
  { id:"789", url:"example4.com"},
]

I'm using a double for loop to compare my objects, but it's painfully slow on a large array... Does anyone have a good solution?

See this fiddle: http://jsfiddle.net/afnvqj49/

I am using only one for loop and saving already processed keys in an object.

var a = [
  { id:"123", url:"example1.com"},
  { id:"123", url:"example2.com"},
  { id:"456", url:"example3.com"},
  { id:"789", url:"example4.com"},
];

var b = [];
var t = {};
for(var i = 0; i < a.length; i++){
    if(t[a[i].id]){
        continue;
    }
    t[a[i].id] = true;
    b.push(a[i]);
}

console.log(b);

Only the first entry for each id is kept

var distinct = function(input, keyExtractor){
   var seen = {}, result = [];
   for(var i = 0, l = input.length; i < l; ++i){
      var key = keyExtractor(input[i]);
      if(seen.hasOwnProperty(key)) {
         continue;
      }
      result.push(input[i]);
      seen[key] = 1;
   }
   return result;
}

var test = [
      { id:"123", url:"example1.com"},
      { id:"123", url:"example2.com"},
      { id:"456", url:"example3.com"},
      { id:"789", url:"example4.com"},
    ];

var u = distinct(test, function(a) { return a.id; });
var reserved = [];
var arr = [
  { id:"123", url:"example1.com"},
  { id:"123", url:"example2.com"},
  { id:"456", url:"example3.com"},
  { id:"789", url:"example4.com"},
];

var result = arr.filter(function(item) {
  var has = ~reserved.indexOf(item.id);
  (!has && reserved.push(item.id));
  return !has;
});

You could use Array.filter (see MDN ), something like

var filtered = [
    { id:"123", url:"example1.com"},
    { id:"123", url:"example2.com"},
    { id:"456", url:"example3.com"},
    { id:"789", url:"example4.com"},
   ].filter( function (v) { 
              return !this[v.id] ? (this[v.id] = true) : false; }, 
            {});
window.idHolder = [];   //its better not to use window object and instead use bind.
var arr = [
  { id:"123", url:"example1.com},
  { id:"123", url:"example2.com},
  { id:"456", url:"example3.com},
  { id:"789", url:"example4.com},
];

var uniqueArr = arr.filter(function(val)
{
if(window.idHolder.indexOf(val.id)!=-1)
{
return false;
}
else
{
window.idHolder.push(val.id);
return true;
}

});

Unique arr will have what you asked for

Since there are plenty of good answers, I just want to throw mine in for fun.

A one-liner using underscore's groupBy and map methods.

_.map(_.groupBy(yourarray,function(element) { return element.id }),function(element) { return element[0] });

PD: is it customary to upvote several answers when they are all correct? perhaps I've been breaking SO Etiquette unknowingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM