【问题标题】:Javascript multi dimensional map and reduce functionJavascript多维map和reduce函数
【发布时间】:2020-01-25 02:54:08
【问题描述】:

我想显示根据用户条件和道具动态变化的菜单:如果它是根目录,是否选择了项目或用户是否有权限。这里是menu 列表对象。

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'] },
    ]

在使用 React 的前端,我会将条件作为数组对象传递给函数,如下所示:

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

pickShownMenus() 函数尝试返回 menu.id 的数组,例如 [3, 4, 5, 7] 用于根目录,[5] 用于未选择项目时的根目录。

问题:我尝试使用 map 和 reduce 函数来获得结果,但它返回的结果与我预期的不同,因为映射的第二次迭代会覆盖所有内容......那么我该如何防止覆盖并接收收集结果?

这是我使用的功能(不工作):

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
}

【问题讨论】:

  • menu.onHidden 数组是否必须包含propsArr 数组的所有元素才能将其id 添加到结果数组中?
  • 比如pickShownMenus([false, 'unselected', false])的结果是什么?
  • @Titus 该示例的结果将是[1, 2, 6]

标签: javascript reactjs mapreduce


【解决方案1】:

所以,根据您提供的情况考虑这种情况:

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,
]

基于此,pickShownMenus 应该是这样的:

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]

  }

【讨论】:

  • 感谢您的回答。在最后一个大括号之前删除不必要的括号后它可以工作;)
  • 你说得对,我会在这里编辑。很高兴它奏效了。记得接受答案并留下一个赞(:这让我们的社区不断发展