0

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?

3
  • Use the id as the index for the array instead? arr[456] = ...? Presumably id == identifier which is unique Commented Aug 19, 2014 at 11:56
  • Please add the code of your double for loop, just to be sure of what you're asking. Commented Aug 19, 2014 at 11:58
  • Is it not possible to do preprocessing to ensure your input isn't formatted like that in the first place? ex: Generate ids from hashing and store in a dictionary. Commented Aug 19, 2014 at 12:02

6 Answers 6

3

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

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

1

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; }, 
            {});

2 Comments

What's the point to use ((this[v.id] = true), true) instead of just (this[v.id] = true)
None whatsoever ;). Removed it.
1
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;
});

Comments

0
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

Comments

0

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.

1 Comment

_.uniq is better: _.uniq(urls, function(url) { return url.id }); :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.