1

I have got two arrays of objects. I want to filter data based on PermissionObj.

This is coming from database. Here are arrays of sub-arrays in the permissionObj.

const PermissionObj = {
  permission: [
    {
      books: [
        {
          label: "Can View",
          value: "can_view"
        }
      ]
    },
    {
      Journals: [
        {
          label: "Can View",
          value: "can_view"
        },
        {
          label: "Can Create",
          value: "can_create"
        }
      ]
    },
    {
      deal: [
        {
          label: "Can update",
          value: "can_update"
        },
        {
          label: "Can delete",
          value: "can_delete"
        }
      ]
    }
  ]
}

this is static data. I want to compare this data based on PermissionObj.

const data = [
  {
    label: "books",
    value: "can_view"
  },
  {
    label: "deal",
    content: [
      {
        value: "can_update"
      },
      {
        value: "can_delete"
      },
      { value: "can_view" }
    ]
  },
  {
    label: "Articles"
  },
  {
    label: "Journals",
    content: [
      {
        value: "can_create"
      },
      {
        value: "can_view"
      },
      {
        value: "can_delete"
      },
      {
        value: "can_edit"
      }
    ]
  }
]

I am trying to filter the data array of the object based on PermissionObj array of objects. here is my trying code.

const permKeys = PermissionObj.permission.flatMap(item => Object.keys(item));
const filteredData = data.filter(({ label }) => permKeys.includes(label));
console.log(filteredData);

Here is my problem, I have been faced is that I don't want to get can_edit, can_delete if it doesn't match with permission objects in journals. In my permission objects, There is no can_edit and can_delete in journals.

My accepted Output would be this format :

const data = [
  {
    label: "books",
    value: "can_view"
  },
  {
    label: "deal",
    content: [
      {
        value: "can_update"
      },
      {
        value: "can_delete"
      }
    ]
  },
  {
    label: "Journals",
    content: [
      {
        value: "can_create"
      },
      {
        value: "can_view"
      }
    ]
  }
]

1 Answer 1

2

It is possible to use reduce method and apply logic to decide what data should be pushed:

const result = data.reduce((a, c) => {
   let filterObj = PermissionObj.permission.find(f => f[c.label]);
   if (filterObj) {
      if (c.value) {
         a.push(c);
      }
      if (c.content) {
         c.content = c.content.filter(f => filterObj[c.label]
             .some(s => s.value.toLowerCase() == f.value.toLowerCase()));
         a.push(c);
      }
   }
   return a;
},[])

An example:

const PermissionObj = {
   permission: [
   {
      "books": [
         {
            "label": "Can View",
            "value": "can_view"
         }
      ]
   },
   {
      "Journals": [
         {
            "label": "Can View",
            "value": "can_view"
         },
         {
            "label": "Can Create",
            "value": "can_create"
         }
      ]
   },
   {
      "deal": [
         {
            "label": "Can update",
            "value": "can_update"
         },
         {
            "label": "Can delete",
            "value": "can_delete"
         }
      ]
   }
 ]
};

const data = [
   {
      label: "books",
      value: "can_view"
   },
   {
      label: "deal",
      content: [
         {
         value: "can_update"
         },
         {
            value: "can_delete"
         },
         {
            value:"can_view"
         }
      ]
   },
   {
      label: "Articles",
   },
   {
      label: "Journals",
      content: [
         {
            value: "can_create"
         },
         {
            value: "can_view"
         },
         {
            value: "can_delete"
         },
         {
            value: "can_edit"
         }
      ]
   }
];


const result = data.reduce((a, c) => {
   let filterObj = PermissionObj.permission.find(f => f[c.label]);
   if (filterObj) {
      if (c.value) {
         a.push(c);
      }
      if (c.content) {
         c.content = c.content.filter(f => filterObj[c.label].some(s => s.value.toLowerCase() == f.value.toLowerCase()));
         a.push(c);
      }
   }
   return a;
},[])
console.log(result);

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

1 Comment

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.