3

I do have this kind of object

var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];

Now I want to skip the duplicate record. Can anyone suggest me the way?

6 Answers6

9

A generic solution to filter out objects with multiple properties.

var list = [{'one':1},{'two':2},{'four':4},{'one':1},{'four':4},{'three':3},{'four':4},{'one':1},{'five':5},{'one':1}];


Array.prototype.uniqueObjects = function(){
    function compare(a, b){
        for(var prop in a){
            if(a[prop] != b[prop]){
                return false;
            }
        }
        return true;
    }
    return this.filter(function(item, index, list){
        for(var i=0; i<index;i++){
            if(compare(item,list[i])){
                return false;
            }
        }
        return true;
    });
}

var unique = list.uniqueObjects();

EDIT:

It won't be possible to compare first or second property as the properties of an object is not in order in javascript. What we can do is compare using property.

Array.prototype.uniqueObjects = function (props) {
    function compare(a, b) {
      var prop;
        if (props) {
            for (var j = 0; j < props.length; j++) {
              prop = props[j];
                if (a[prop] != b[prop]) {
                    return false;
                }
            }
        } else {
            for (prop in a) {
                if (a[prop] != b[prop]) {
                    return false;
                }
            }

        }
        return true;
    }
    return this.filter(function (item, index, list) {
        for (var i = 0; i < index; i++) {
            if (compare(item, list[i])) {
                return false;
            }
        }
        return true;
    });
};

var uniqueName = list.uniqueObjects(["name"]);
var uniqueAge = list.uniqueObjects(["age"]);
var uniqueObject = list.uniqueObjects(["name", "age"]);

http://jsbin.com/ahijex/4/edit

Diode
  • 24,570
  • 8
  • 40
  • 51
  • Thanks tracevipin..it really helped :). But is there any way if I want to go through particular field. Like if object has two key value and I want to match only second key value for each object? –  May 30 '13 at 13:07
  • @djtechie Do keep in mind the the [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FArray%2Ffilter) method is available only in ECMAScript 5. The only browsers you have to worry about not having this function is IE 8 and below. – Amy May 30 '13 at 20:12
  • We can use indexOf for array then what is for object? –  May 30 '13 at 20:24
  • @djtechie if you want here filter function can be replaced with a for loop resulting in a nested loop. Object keys are not indexed in Javascript. By ECMA standard keys should be indexed in the order they are added to the object. But we cannot rely on this as all browsers do not support that behavior. – Diode May 31 '13 at 06:09
0

1) Make a loop through the array.
2) Within that loop, loop through the object
3) Save the key in a global variable
4) If the key already exists, remove the object from the array.

But tbh, what's the point of creating an array of objects, instead of one big object? Then any duplicate keys will automatically be overridden...

Like

{
  "one" : 1,
  "two" : 2
  ...
}
Joris Kroos
  • 431
  • 3
  • 17
  • I'm getting that array from an API and I can't change the format of output :) that's why. Will you give me an example code of your explanation? –  May 30 '13 at 19:25
0

you could do something like:

var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];
var keyarr = [];
var unique = [];

j.map(function(obj, index) {
    for(var key in obj ) {
        console.log( key );
        if( $.inArray(key, keyarr) < 0 ) {
            var newobj = {};
            newobj[key] = obj[key];
            unique.push(newobj)
        }
    }
});
console.log( unique );

Demo jsfiddle

Sudhir Bastakoti
  • 99,167
  • 15
  • 158
  • 162
0

You can use "map" aka object to keep track of distinct objects. Assuming uniqueness is defined by both the key and value being the same.

var data = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}];
var tempMap = {};    // keep track of unique objects with key mapping to the object's key&value
var distinct = [];    // resulting list containing only unique objects
var obj = null;
for (var i = 0; i < data.length; i++) {
    obj = data[i];
    for (var key in obj) {        // look in the object eg. {'one':1}
        if (obj.hasOwnProperty(key)) {
            if (!tempMap.hasOwnProperty(key + obj[key])) {    // not in map
                tempMap[key + obj[key]] = obj;        // then add it to map
                distinct.push(obj);    // add it to our list of distinct objects
            }
            break;
        }
    }
}
console.log(distinct);   // list of distinct objects

See fiddle: http://jsfiddle.net/amyamy86/saSqt/

Amy
  • 7,388
  • 2
  • 20
  • 31
0

Try this too:

var j = [{'one':1},{'two':2},{'three':3},{'four':4},{'five':5},{'one':1}],
d = [],
key = [];
d = j.slice(0);
function getKeys(obj) {
    var r = []
    for (var k in obj) {
        if (!obj.hasOwnProperty(k)) 
            continue
        r.push(k)
    }
    return r
}
for(var i=0; i< d.length; i++){
    key.push(getKeys(d[i]));
}

for(var kI = 0; kI < key.length; kI++){
    for(var kJ = 0; kJ < key.length; kJ++){
        if(kI !== kJ && key[kI][0] === key[kJ][0]){
            key.splice(kJ,1);     
            d.splice(kJ,1);
        }
    }
}
console.log(j);
console.log(d);

Working fiddle

Mr_Green
  • 40,727
  • 45
  • 159
  • 271
0

Check out Linq for JavaScript (linq.js), a free JavaScript library available at CodePlex:

https://linqjs.codeplex.com/

You can try out code snippets live on the reference page (included in the linqpad package, unzip it first - then paste the code snippet into the code box and the result is shown immediately):

LinqJS\linq.js_ver2.2.0.2\reference.htm

Like C# LINQ it has a .distinct method allowing to do the job for your JSON array as a one-liner, for example:

var array = [100, 200, 30, 40, 500, 40, 200];
var ex1 = Enumerable.From(array).Distinct().ToArray(); // [100, 200, 30, 40, 500]

It has most of the methods you know from C# LINQ and comes either as a non-jQuery or as a jQuery version with full NUGET support.

Arrays with named properties like the one you have in your example are supported too, e.g.:

var list = [
       { one: 2, two: 4, three: 1 },
       { one: 4, two: 7, three: 5 },
       { one: 2, two: 4, three: 1 },
       { one: 7, two: 3, three: 2 },
       ];
Enumerable.From(list).Distinct("$.one")
.OrderBy("$.a").ThenBy("$.two").ThenBy("$.three")
.Select("$.one + ':' + $.two + ':' + $.three")

Gives you the result:

2:4:1
4:7:5
7:3:2

Matt
  • 25,467
  • 18
  • 120
  • 187