9

I have an array of objects like this -

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4}
];

I want to remove the duplicates having same type_id and full_empty values. The result should look like this -

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
];

I have searched and found some solution, but some of them are for removing duplicate keys or for removing duplicates based on duplicate value of only one key. Some required external libraries. Also there are some solutions which i can't understand. Is there any easy way to do this in plain JavaScript ?

Edit for better understand - I have read this question . Accepted answer on that question is for finding duplication for only one key. In my case, I have to find the duplication for multiple keys.

Community
  • 1
  • 1
ni8mr
  • 1,725
  • 3
  • 31
  • 58
  • Possible duplicate of [Remove duplicates from an array of objects in javascript](http://stackoverflow.com/questions/2218999/remove-duplicates-from-an-array-of-objects-in-javascript) – Rohit416 Jun 27 '16 at 05:15
  • @Rohit416 I have tried to implement that solution. But it was searching for duplicate value in only one key. In my case, i have to search for duplicate values in multiple keys. – ni8mr Jun 27 '16 at 05:17
  • But if the array is `var arr = [ { type_id: "3", full_empty:"true", quantity:1}, { type_id: "3", full_empty:"true", quantity:2}, ... ];` What result do you expect? – Van M. Tran Jun 27 '16 at 05:17

9 Answers9

13

You can use pure functions by using Array.some() and Array.reduce() to reduce your input array to array of distinct elements as shown below

    var arr = [
        { type_id: "3", full_empty:"true", quantity:1},
        { type_id: "3", full_empty:"true", quantity:1},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"false", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4},
        { type_id: "9", full_empty:"true", quantity:4}
    ];

    var a = arr.reduce(function (accumulator, current) {
      if (checkIfAlreadyExist(current)) {
        return accumulator
      } else {
        return accumulator.concat([current]);
      }
      
      function checkIfAlreadyExist(currentVal) {
        return accumulator.some(function(item){
          return (item.type_id === currentVal.type_id &&
                  item.full_empty === currentVal.full_empty);
        });
      }
    }, []);
        
    console.log(a);

Concise ES6 syntax

A more concise reduce can be written using ES6 arrow functions and spread operator as below:

var arr = [
            { type_id: "3", full_empty:"true", quantity:1},
            { type_id: "3", full_empty:"true", quantity:1},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"false", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4},
            { type_id: "9", full_empty:"true", quantity:4}
        ];

var a = arr.reduce((accumulator, current) => {
  if (checkIfAlreadyExist(current)) {
    return accumulator;
  } else {
    return [...accumulator, current];
  }

  function checkIfAlreadyExist(currentVal) {
    return accumulator.some((item) => {
      return (item.type_id === currentVal.type_id &&
              item.full_empty === currentVal.full_empty);
    });
  }
}, []);
            
console.log(a);
Aditya Singh
  • 15,810
  • 15
  • 45
  • 67
  • Thanks, your answer has solved the problem. Many of the answers are missing one key point- I have to search for duplication in case of more than one keys. – ni8mr Jun 27 '16 at 05:30
  • @ni8mr My pleasure :). please accept the answer if it works for you – Aditya Singh Jun 27 '16 at 05:36
5

Despite the other solutions, I suggest to use a hash table with type_id and full_empty as key and if a new found then set hash to true. Together with Array#filter, you get a new array with the unique items.

var arr = [{ type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }],
    filtered = arr.filter(function (a) {
        var key = a.type_id + '|' + a.full_empty;
        if (!this[key]) {
            this[key] = true;
            return true;
        }
    }, Object.create(null));

console.log(filtered);

ES6

var arr = [{ type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }],
    filtered = arr.filter(
        (temp => a =>
            (k => !temp[k] && (temp[k] = true))(a.type_id + '|' + a.full_empty)
        )(Object.create(null))
    );

console.log(filtered);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1
//To search the element is already exisit or not.(to remove Duplicate)
    function searchExisting(type_id,full_empty,newArray){
        for(var i=0;i<newArray.length;i++){
            if(newArray[i].type_id==type_id && newArray[i].full_empty==full_empty){
                return true;
            }
        }
        return false;
    }

//loop through every element and push it into new array
    var arr2=[];
    for(var i=0;i<arr.length;i++){
        if(!searchExisting(arr[i].type_id,arr[i].full_empty,arr2)){
            arr2.push(arr[i]);
        }
    }
    console.log(arr2)
Dipak Prajapati
  • 486
  • 5
  • 13
1

You can use find and forEach to create a new array from this array which contain duplicate values

Hope this snippet will be useful

var arr = ["Json Array object as supplied in the question"];

// A new array which will contain unique json object
var newArray = [];

//Loop through each of the object in the original array

arr.forEach(function(item) {
    // If newArray .length is zero then just push the first element
    // else in newArray find if a json object already exist which have same
    // type_id & full_empty. If it does not exist it will return undefined
    if (newArray.length !== 0) {
        var _isPresent = newArray.find(function(secItem) {
            return secItem.type_id === item.type_id && secItem.full_empty === item.full_empty
        })
        // If element is not present then push this json pbject
        if (_isPresent == undefined) {
            newArray.push(item)
        }
    } else {  // this will execute only once when newArray length is 0

        newArray.push(item)
    }
})
console.log(newArray)

JSFIDDLE

brk
  • 48,835
  • 10
  • 56
  • 78
1

This not as awesome as Ninas answer but can be noticed and a new answer.

var arr = [ { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "3", full_empty: "true", quantity: 1 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "false", quantity: 4}, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4 }, { type_id: "9", full_empty: "true", quantity: 4}];

var dict = {}, result = [];

arr.forEach((i, key) => {
  !dict[(key = i.type_id + i.full_empty)] 
      && (dict[key] = result.push(i));
})
console.log(result)
Community
  • 1
  • 1
Morteza Tourani
  • 3,506
  • 5
  • 41
  • 48
0

The array object has filter and map on it. You can use filter to target the properties of the inactive that you want. It a boolean evaluation that returns a "filtered" new array.

Here is a great video tutorial posted on the Egghead.IO site that really breaks it down.

andre mcgruder
  • 1,120
  • 1
  • 9
  • 12
0

If you don't want to get into code so you can use below snippet :-

var sDat = [
{ sid:12, scode:"code", sname:"Deep" },
{ sid:12, scode:"code", sname:"Anand" },
{ sid:139, scode:"code", sname:"Singh"}
];

function cleanup(arr, prop) {
var new_arr = [];
var lookup  = {};

for (var i in arr) {
    lookup[arr[i][prop]] = arr[i];
}

for (i in lookup) {
    new_arr.push(lookup[i]);
}

return new_arr;
}

var n = cleanup(sDat, 'sid');
alert(n);

I hope this will work for you.

Anand Deep Singh
  • 2,560
  • 3
  • 22
  • 28
  • It works but with your code i can only check for duplicate value in case of one key. I need to do it in case of multiple keys, at once. Btw, thanks. – ni8mr Jun 27 '16 at 05:58
0

This is my modified version of Aditya Singh's answer

var arr = [
                { type_id: "3", full_empty:"true", quantity:1},
                { type_id: "3", full_empty:"true", quantity:1},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"false", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4},
                { type_id: "9", full_empty:"true", quantity:4}
            ];


    var a = arr.reduce((accumulator, current) => {

     const isAlreadyExist = accumulator.some(item => (
      item.type_id === currentVal.type_id && item.full_empty === currentVal.full_empty
     ))

     return isAlreadyExist(current) ? accumulator : [...accumulator, current];
    }, []);

    console.log(a);
Jeex Box
  • 157
  • 2
  • 6
0

var arr = [
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "3", full_empty:"true", quantity:1},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"false", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4},
    { type_id: "9", full_empty:"true", quantity:4}
];

let op = [];

arr.forEach((el) => {
  if (isNotExist(el)){
    op.push(el)
  }
  function isNotExist(obj){
    return op.every(el => JSON.stringify(el) !== JSON.stringify(obj) )
   
  }
})

console.log(op)