【问题标题】:how to filter array of object and nested of array如何过滤对象数组和数组嵌套
【发布时间】:2020-07-18 09:50:18
【问题描述】:

我有两个嵌套对象数组。我想根据permissionObj过滤数据。

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

我需要在 reduce 函数中做另一个条件。例如,如果 Pubsidebar 的值是令牌是公共的,我想保留静态内容 {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"
          }
        ]
      }
    ]

【问题讨论】:

    标签: javascript arrays reactjs object functional-programming


    【解决方案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 中,所以我无法添加 - 因为我不知道它来自哪里

    【讨论】:

    • 没看懂你的概念,你加sn-p?
    • 在你的问题中你有 permissionObj - 我正在走这个以获得部分输出 - 你的输出的其余部分不在你提供的对象中 - 所以我无法理解
    • 你可以达到我预期的输出
    【解决方案2】:

    您可以在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)

    【讨论】:

    • 如果我从 token 中删除 can_create ,我看不到其他属性
    • @sujon 因为您的 tokenpermissionObj 具有值 can_create。所以filter 方法有效
    • 我想在 pubSidebar 中设置常量令牌,子数组属性将根据 permissionobj 进行添加/删除。
    • { label: 'token', value: 'public', content: [ { key: 'test', value: 'public', }, ], },这将是常量,但是 token将根据令牌添加/删除
    • @sujon 作为一种好的做法,您需要在发布问题之前写下所有条件。人家回答后,再改变你的要求是不行的,因为这是回答你的人的新努力。在我看来,您需要提出新问题或展示您的努力
    猜你喜欢
    • 2022-12-03
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2020-03-11
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    相关资源
    最近更新 更多