0

I have two arrays such as,

Array 1:

    deletedValuesfromArray =
     [
        { "property_name": "Property three", "property_type": 4, "property_required": true, "property_origin": 2 }, 
        { "property_name": "rstywrtre", "property_type": 3, "property_required": true, "property_origin": 1 }
     ]

Array 2:

  normalArray =
   [
    { "property_name": "Property one", "property_type": 4, "property_required": true, "property_origin": 1 },
     { "property_name": "Property two", "property_type": 5, "property_required": true, "property_origin": 1 }, 
     { "property_name": "Property three", "property_type": 4, "property_required": true, "property_origin": 2 }, 
     { "property_name": "rstywrtre", "property_type": 3, "property_required": true, "property_origin": 1 }
   ]

I would like to compare both arrays and filter the array to get the new one after removing the deletedValuesfromArray (Array 1).

For which i have tried the following,

let newArray = this.normalArray.filter(function (val) {
  return this.deletedValuesfromArray.indexOf(val) == -1;
});
console.log(newArray);

But it doesn't works..

Expected Output is,

New Array

   [
     { "property_name": "Property one", "property_type": 4, "property_required": true, "property_origin": 1 },
     { "property_name": "Property two", "property_type": 5, "property_required": true, "property_origin": 1 }
   ]

Stackblitz that i have tried

The values also will not be unique always it may have a complete duplicate of any object.

How to compare and remove the deleted values from the normal array and get the newarray?

James Z
  • 11,838
  • 10
  • 25
  • 41
Maniraj Murugan
  • 6,412
  • 10
  • 56
  • 92

5 Answers5

1

Your filter predicate doesn't work because you can't just compare an object from normalArray to an object from deletedValuesfromArray:

indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the === or triple-equals operator).

-- Array.indexOf()

In other words,

{ "property_name": "Property one", "property_type": 4, "property_required": true, "property_origin": 1 } === { "property_name": "Property one", "property_type": 4, "property_required": true, "property_origin": 1 }
// > false

To make the filter work, you need to implement a comparison function. See How to determine equality for two JavaScript objects? for some ideas.

shkaper
  • 3,514
  • 1
  • 15
  • 31
0

You can proceed with ES6 operators (filter and some) :

 ngOnInit() {
    let newArray = this.normalArray.filter( (val) => {
      return !this.deletedValuesfromArray.some((newval) => {
       return JSON.stringify(newval) === JSON.stringify(val) // check if two objects are the same
      });
    });
    console.log(newArray);
  }
selem mn
  • 8,212
  • 4
  • 28
  • 46
  • Here you're assuming that `property_name` values are unique. The OP never said that – shkaper Nov 14 '18 at 13:42
  • Yes this solution seems to be close to me but the thing is as @shkaper said the values may not be unique at all time.. – Maniraj Murugan Nov 14 '18 at 13:58
  • 3
    this is potentially dangerous since object's property order is not guaranteed in JavaScript – shkaper Nov 14 '18 at 14:55
  • If you need an explanation about why this solution is terrible, please consider how much cpu time is wasted to stringify all those objects. You are also stringifying the same object way too many times with the way this loop works. You are also not taking into account that there is no spec in javascript that says that the order of object properties stays the same. – itsundefined Nov 14 '18 at 20:58
0

one of simple options here you can use JSON.stringify, which will turn objects into strings and compare them as strings, because 2 objects never equal each other by value since it compares them by reference, make sure that your objects keys order are the same

const deletedValuesfromArray =
     [
        { "property_name": "Property three", "property_type": 4, "property_required": true, "property_origin": 2 }, 
        { "property_name": "rstywrtre", "property_type": 3, "property_required": true, "property_origin": 1 }
     ]

  const normalArray =
   [
    { "property_name": "Property one", "property_type": 4, "property_required": true, "property_origin": 1 },
     { "property_name": "Property two", "property_type": 5, "property_required": true, "property_origin": 1 }, 
     { "property_name": "Property three", "property_type": 4, "property_required": true, "property_origin": 2 }, 
     { "property_name": "rstywrtre", "property_type": 3, "property_required": true, "property_origin": 1 }
   ]

const result = normalArray.filter(obj => !deletedValuesfromArray.find(o => JSON.stringify(o) == JSON.stringify(obj)));

console.log(result);
Artyom Amiryan
  • 2,478
  • 1
  • 7
  • 18
  • what if the order of keys is different in two same-looking objects? – shkaper Nov 14 '18 at 13:35
  • @shkaper the order is important in my example, I will update my answer – Artyom Amiryan Nov 14 '18 at 13:36
  • I can explain the down vote. Using stringify is a terrible solution and the guy that made the question didn't say that he wants to check that the two objects are exactly identical. You should *NEVER* expect that the order of keys is the same. – itsundefined Nov 14 '18 at 20:50
  • 1
    @itsundefined from the question it is easy to get that he wants to check that the two objects are exactly identical. Almost all answers contain the same logic, as accepted answer too which marked by question creator, it means we got question right, and I noted that in my example order is important, so I don't see any reason for down vote, it seems you got question wrong and added down votes to answers which have upvote – Artyom Amiryan Nov 14 '18 at 21:02
  • @itsundefined I'm not using this method for removing objects from array, I'm using this method for comparing objects, 2 different things – Artyom Amiryan Nov 14 '18 at 21:05
  • https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order . Here is the reason for the downvote – itsundefined Nov 14 '18 at 21:05
0

Using lodash :-

npm install --save lodash


import * as _ from "lodash";

var newArray = _.differenceWith(this.normalArray, this.deletedValuesfromArray, _.isEqual);
console.log("newArray", newArray);
Chandru
  • 9,360
  • 3
  • 32
  • 50
0

This might also help you.

function display()
{
  let newArray = this.normalArray.filter(function (val) {
  count = 0;
  var flag = true;
  return this.deletedValuesfromArray.find(function(item, i){
  count++;

     if(val.property_name == item.property_name && val.property_type == item.property_type && val.property_required == item.property_required && val.property_origin == item.property_origin ){
       flag =  false;
     }
     if(count == deletedValuesfromArray.length) {
     return flag;
     }
  });

}); }

Pratik Rathi
  • 51
  • 1
  • 9