How to filtering between array of sub arrays and array of sub arrays in javascript?

白昼怎懂夜的黑 提交于 2020-04-06 19:23:46

问题


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:


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);


来源:https://stackoverflow.com/questions/60831082/how-to-filtering-between-array-of-sub-arrays-and-array-of-sub-arrays-in-javascri

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!