2

I would like to achieve the following by filtering and mapping the two array of nested objects using the map and filter in the angular.

I have got one solution in regards to my last question to filter based on specific property.

manipulate two array of objects make new array and update the attribute of object1 and add in the new array

but I am not sure how to filter different objects based on different properties.

I want to filter some object using id property and some using the val... is it possible?

  • i would like to compare type1 and type2 based on val
  • i would like to compare type1 and type2 data object using dataid
  • i would like to compare type3/type4 based on id..

const obj1 = [
   {
      "val":"type1",
      "removed":"N",
      "id":1,
      "data":[
         {
            "label":"type1-a",
            "removed":"N",
            "dataid":16
         },
         {
            "label":"type1-b",
            "removed":"N",
            "dataid":26
         }
      ]
   },
   {
      "val":"type2",
      "removed":"N",
      "id":2,
      "data":[
         {
            "label":"type2-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type2-b",
            "removed":"N",
            "dataid":34
         }
      ]
   },
   {
      "val":"type3",
      "removed":"N",
      "id":124,
      "label":"type3-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":126,
      "label":"type4-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":128,
      "label":"type4-label2"
   }
]

const obj2 = [
   {
      "val":"type1new",
      "removed":"N",
      "id":1
      "data":[
         {
            "label":"type1new",
            "removed":"N",
            "dataid":16
         },
         {
            "label":"type1-c",
            "removed":null,
            "dataid":null
         },
         {
            "label":"type1-d",
            "removed":null,
            "dataid":null
         }
      ]
   },
   {
      "val":"type3",
      "removed":"N",
      "id":124,
      "label":"type3-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":126,
      "label":"type4-label1"
   },
   {
      "val":"type3",
      "removed":null,
      "id":128,
      "label":"new"
   }
]


result = [
   {
      "val":"type1new",
      "removed":"N",
      "id":1,
      "data":[
         {
            "label":"type1new",
            "removed":"N",
            "dataid":16
         },
         {
            "label":"type1-b",
            "removed":"Y",
            "dataid":26
         },
         {
            "label":"type1-c",
            "removed":null,
            "dataid":null
         },
         {
            "label":"type1-d",
            "removed":null,
            "dataid":null
         }
      ]
   },
   {
      "val":"type2",
      "removed":"Y",
      "data":[
         {
            "label":"type2-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type2-b",
            "removed":"N",
            "dataid":34
         }
      ]
   },
   {
      "val":"type3",
      "removed":"N",
      "id":124,
      "label":"type3-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":126,
      "label":"type4-label1"
   },
   {
      "val":"type4",
      "removed":"Y",
      "id":128,
      "label":"type4-label2"
   },
   {
      "val":"type4",
      "removed":null,
      "id":null,
      "label":"type4-label3"
   },
   {
      "val":"type3",
      "removed":null,
      "id":128,
      "label":"new"
   }
]

---updated question above---

1 Answer 1

3

Here's how I would tackle it

const obj1 = [
   {
      "val":"type1",
      "removed":"N",
      "data":[
         {
            "label":"type1-a",
            "removed":"N",
            "dataid":16
         },
         {
            "label":"type1-b",
            "removed":"N",
            "dataid":26
         }
      ]
   },
   {
      "val":"type2",
      "removed":"N",
      "data":[
         {
            "label":"type2-a",
            "removed":"N",
            "dataid":12
         },
         {
            "label":"type2-b",
            "removed":"N",
            "dataid":34
         }
      ]
   },
   {
      "val":"type3",
      "removed":"N",
      "id":124,
      "label":"type3-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":126,
      "label":"type4-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":128,
      "label":"type4-label2"
   }
]

const obj2 = [
   {
      "val":"type1",
      "removed":"N",
      "data":[
         {
            "label":"type1-a",
            "removed":"N",
            "dataid":16
         },
         {
            "label":"type1-c",
            "removed":null,
            "dataid":null
         },
         {
            "label":"type1-d",
            "removed":null,
            "dataid":null
         }
      ]
   },
   {
      "val":"type3",
      "removed":"N",
      "id":124,
      "label":"type3-label1"
   },
   {
      "val":"type4",
      "removed":"N",
      "id":126,
      "label":"type4-label1"
   },
   {
      "val":"type3",
      "removed":null,
      "id":128,
      "label":"new"
   }
]


const getIdentity = (obj) => {
  if(["type1", "type2"].includes(obj.val)) {
    return obj.val;
  }

  if(["type3", "type4"].includes(obj.val)) {
    return obj.id + obj.val;
  }
}

const result = obj1.reduce((acc, obj) => {

  const similarObj = obj2.find(nobj => getIdentity(nobj) === getIdentity(obj));
  
  if(["type1", "type2"].includes(obj.val) && similarObj) {
    const data = obj.data.reduce((nacc, item) => {
      
      const similarItem = similarObj.data.find(pr => pr.dataid === item.dataid);
      
      if(!similarItem) {

        return [...nacc, {...item, removed: 'Y'}];
      }
      
      const newItem = {
        ...item,
        ...similarItem
      }
      
      return [...nacc, newItem];
    }, similarObj.data.filter(pr => !obj.data.some(npr => pr.dataid === npr.dataid)))
    
    const newObj = {
      ...obj,
      ...similarObj,
      data
    }
    
    return [...acc, newObj];
  }
  
  if(!similarObj) {
    acc = [...acc, {
      ...obj,
      removed: "Y"
    }];
    
    return acc;
  }
  
  return [...acc, obj];

}, obj2.filter(obj => !obj1.some(nobj => getIdentity(obj) === getIdentity(nobj))))

result.sort((prev, next) => prev.val > next.val ? 1 : -1);

console.log(result);

Ideally every object would contain its unique id and type which decides if there should be additional processing. Thats my thought.

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

9 Comments

thanks for all answers... it works on all conditions except when object2 updates val in the object1 existing id to this {"val":"type3","removed":null, "id":128, "label":"new label"}... result is not updating with the { "val":"type4", "removed":"Y", "id":128,"label":"type4-label2"}
The rule was to compare objects by id when they are of type type3,type4. Now it is not the case?
I modified the function which gets identity from the object return obj.id + obj.val;. It seems to handle mentioned case but I am not sure about the other ones
Thanks a lot.. now I am having the unique id for all the types.
You have to change getIdentity function as it checks what's inside val property. I am not sure about reduce implementation.
|

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.