简体   繁体   中英

Javascript multi dimensional map and reduce function

I would like to display menu which dynamically changes depends on the user conditions and props which are : if it's root directory, if item is selected or if user have a permission. And here are the menu list object.

const menus = [
      { 'id': 1, 'onHidden': ['root', 'user'] },
      { 'id': 2, 'onHidden': ['root', 'user'] },
      { 'id': 3, 'onHidden': ['user', 'unselected'] },
      { 'id': 4, 'onHidden': ['user', 'unselected'] },
      { 'id': 5, 'onHidden': ['unselected'] },
      { 'id': 6, 'onHidden': ['root', 'user'] },
      { 'id': 7, 'onHidden': ['user', 'unselected'] },
    ]

And on the front end with React, I will pass the conditions to the function as an array object like this:

const shownMenues = pickShownMenus([
      this.props.parent === 0 ? 'root' : false,
      this.props.selected < 0 ? 'unselected' : false,
      this.props.user.permission > 2 ? 'user' : false,
    ])

on pickShownMenus() function tries to return an array of menu.id such as [3, 4, 5, 7] for root directory, [5] for root directory when item is not selected.

question: I've tried to use map and reduce function to get a result but it returns different from that I expected because second iteration of mapping will overwrite everything.... So how can I prevent overwriting and receive a collect result?

Here is the function that I used (not working) :

const pickShownMenus = (props) => {
  const p = props.slice()
  const propsArr = p.filter((x) => x != false)
  const reduce = menus.reduce((arr, menu) => {
    propsArr.map((props) => {
      if (menu.onHidden.indexOf(props) < 0) {
        arr.push(menu.id)
      }
    })
    return arr
  }, [])

  return reduce
}

So, considering have this situation based on what you've provided:

const menus = [
  { 'id': 1, 'onHidden': ['root', 'user'] },
  { 'id': 2, 'onHidden': ['root', 'user'] },
  { 'id': 3, 'onHidden': ['user', 'unselected'] },
  { 'id': 4, 'onHidden': ['user', 'unselected'] },
  { 'id': 5, 'onHidden': ['unselected'] },
  { 'id': 6, 'onHidden': ['root', 'user'] },
  { 'id': 7, 'onHidden': ['user', 'unselected'] },
]

const props = {
  parent: 1,
  selected: -1,
  user: {
    permission: 1
  }
};

const params = [
  props.parent === 0 ? 'root' : false,
  props.selected < 0 ? 'unselected' : false,
  props.user.permission > 2 ? 'user' : false,
]

Based on that, the pickShownMenus should be something like this:

const pickShownMenus = (params) => {
    const filtered_params = params
        .filter(elm => !!elm) // Remove the falses
    return menus
        .filter(menu => 
          menu.onHidden
            .some(onHiddenDirective => 
              filtered_params
                .find(filtered_param => 
                  filtered_param === onHiddenDirective
                )
            )
        )
        .map(menu => menu.id) // output: [3, 4, 5, 7]

  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM