如何过滤对象数组和数组嵌套

时间:2020-04-06 11:47:45

标签: javascript arrays reactjs object functional-programming

我有两个嵌套对象数组。我想根据PermissionObj筛选数据。

这来自数据库。这是permissionObj中的子数组的数组。

我需要在reduce函数中做另一个条件。例如,如果Pubsidebar的值是token是public,我想保留静态内容{label:“ test”,value:“ public”}而不用PermissionObj过滤,并且如果其他键和值与PermissionObj匹配,则将其推送内部令牌。

    let permissionObj = [
      {
        'OA deal': [
          {
            label: 'can view',
            value: 'can_view',
          },
        ],
      },


      {
        Deposit: [
          {
            label: 'can_view',
            value: 'can_view',
          },
        ],
      },

      {
        Journals: [
          {
            label: 'can create',
            value: 'can_create',
          },
        ],
      },
      {
        Dashboard: [
          {
            label: 'can view',
            value: 'can_view',
          },
        ],
      },
      {
        token: [
          {
            label: 'can view',
            value: 'can_create',
          },
        ],
      },
    ]

    const PubSidebar = [
      {
        label: 'Dashboard',
        value: 'can_view',
      },{
        label: 'transction',
value:"public",content:[{label:"test2",value:"public"}]

},
      {
        label: 'token',
        value: 'public',
        content: [
          {
            key: 'token',
            value: 'can_create',
          },
          {
            key: 'test',
            value: 'public',
          },
        ],
      },
      {
        label: 'OA deal',
        content: [
          {
            label: 'view oadeal',
            key: 'OA deal',
            value: 'can_view',
          },

          {
            label: 'Deposit',
            key: 'Deposit',
            value: 'can_view',
          },
          {
            label: 'Corrections',
            key: 'Corrections',
            value: 'can_edit',
          },
        ],
      },
      {
        label: 'Journals',
        content: [
          {
            label: 'Add Journal',
            key: 'Journals',
            value: 'can_create',
          },
        ],
      },
    ]

    const filterObject = permissionObj.reduce((a, c) => {
      for (const key in c) {
        a[key] = c[key]
      }
      return a
    }, {})
    const result = PubSidebar.reduce((a, c) => {
      if (
        filterObject[c.label] &&
        c.value &&
        filterObject[c.label].some(s => s.value === c.value)
      ) {
        a.push(c)
      } else if (c.value === 'public' && c.label === 'token') {
        if (
          (c.content = c.content.filter(
            f =>
              filterObject[f.key] &&
              filterObject[f.key].some(s => s.value == f.value)
          ))
        ) {
          c.content = c.content.filter(
            f =>
              filterObject[f.key] &&
              filterObject[f.key].some(s => s.value == f.value)
          )
          a.push(c)
        }
      } else if (c.content.some(s => filterObject[s.key]) && c.content) {
        c.content = c.content.filter(
          f =>
            filterObject[f.key] && filterObject[f.key].some(s => s.value == f.value)
        )
        a.push(c)
      }

      return a
    }, [])

    console.log(result)

我正在尝试从侧边栏获取公共数据,而无需使用PermissionObj进行过滤。

我的预期输出将是:

    [
      {
        "label": "Dashboard",
        "value": "can_view"
      },
{
            label: 'transction',
    value:"public",content:[{label:"test2",value:"public"}]

    },
      {
        "label": "token",
        "value": "public",
        "content": [{
            "key": "test",
            "value": "public"
          }
          {
            "key": "token",
            "value": "can_create"
          }
        ]
      },
      {
        "label": "OA deal",
        "content": [
          {
            "label": "view oadeal",
            "key": "OA deal",
            "value": "can_view"
          },
          {
            "label": "Deposit",
            "key": "Deposit",
            "value": "can_view"
          }
        ]
      },
      {
        "label": "Journals",
        "content": [
          {
            "label": "Add Journal",
            "key": "Journals",
            "value": "can_create"
          }
        ]
      }
    ]

2 个答案:

答案 0 :(得分:1)

您可以在reduce方法内添加条件,并且您的content属性将不会被过滤:

if (c.value ==='public' && c.content.some(f => filterObject[f.key] && 
    filterObject[f.key].some(s => s.value == f.value))) {
        a.push(c);
}

并尝试避免在filter条件内if使用您的数据。

所以代码看起来像这样:

let permissionObj = [
  {
    'OA deal': [
      {
        label: 'can view',
        value: 'can_view',
      },
    ],
  },

  {
    Deposit: [
      {
        label: 'can_view',
        value: 'can_view',
      },
    ],
  },

  {
    Journals: [
      {
        label: 'can create',
        value: 'can_create',
      },
    ],
  },
  {
    Dashboard: [
      {
        label: 'can view',
        value: 'can_view',
      },
    ],
  },
  {
    token: [
      {
        label: 'can view',
        value: 'can_create',
      },
    ],
  },
]

const PubSidebar = [
  {
    label: 'Dashboard',
    value: 'can_view',
  },
  {
    label: 'token',
    value: 'public',
    content: [
      {
        key: 'token',
        value: 'can_create',
      },
      {
        key: 'test',
        value: 'public',
      },
    ],
  },
  {
    label: 'OA deal',
    content: [
      {
        label: 'view oadeal',
        key: 'OA deal',
        value: 'can_view',
      },

      {
        label: 'Deposit',
        key: 'Deposit',
        value: 'can_view',
      },
      {
        label: 'Corrections',
        key: 'Corrections',
        value: 'can_edit',
      },
    ],
  },
  {
    label: 'Journals',
    content: [
      {
        label: 'Add Journal',
        key: 'Journals',
        value: 'can_create',
      },
    ],
  },
]



const filterObject = permissionObj.reduce((a, c) => {
  for (const key in c) {
    a[key] = c[key]
  }
  return a
}, {})




const result = PubSidebar.reduce((a, c) => {
  if (filterObject[c.label] && c.value && filterObject[c.label].some(s => s.value === c.value)) {
      a.push(c)
  } else if (c.value === 'public' && c.label === 'token') {
      if (c.value ==='public' && c.content.some(f => filterObject[f.key] && filterObject[f.key].some(s => s.value == f.value))) {
          a.push(c);
      }
      else {
          c.content = c.content.filter(f => filterObject[f.key]
              &&  filterObject[f.key].some(s => s.value == f.value));
          a.push(c);
      }
  } else if (c.content.some(s => filterObject[s.key]) && c.content) {
      c.content = c.content.filter(
        f =>
          filterObject[f.key] && filterObject[f.key].some(s => s.value == f.value)
      )
      a.push(c)
  }

  return a
}, [])

console.log(result)

答案 1 :(得分:-1)

我尝试使用您在问题(permissionObj)中提供的对象

permissionObj.map( 
  p =>{  
    return { 
      label: Object.keys(p)[0], value:p[Object.keys(p)[0]][0].value 
    }
  }
)

遍历键,并以第一个作为标签和它的第一个子数组对象来获取值

结果:

[{"label":"OA deal","value":"can_view"},{"label":"Deposit","value":"can_view"},{"label":"Journals","value":"can_create"},{"label":"Dashboard","value":"can_view"},{"label":"token","value":"can_create"}]

您需要的某些数据不在PermissionObj中,所以我无法添加它-因为我不知道那是哪里来