首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript :只使用一个子级别

Javascript :只使用一个子级别
EN

Stack Overflow用户
提问于 2019-03-13 10:16:57
回答 2查看 157关注 0票数 0

鉴于以下数据结构:

代码语言:javascript
复制
[  
  {  
     "name":"root",
     "children":[  
        {  
           "name":"de",
           "children":[  
              {  
                 "name":"de",
                 "children":[
                    {  
                       "name":"project-1",
                       "children":[  
                       ]
                    },
                    {  
                       "name":"project-2",
                       "children":[  
                       ]
                    }
                 ]
              }
           ]
        }
     ]
  }
]

预期:

代码语言:javascript
复制
[
  {
     "name":"project-1",
     "children":[
     ]
  },
  {
     "name":"project-2",
     "children":[
     ]
  }
]

如果只有一个孩子,我想删除一个级别。在本例中,我希望有一个新数组,它只包含" root“级别的子级,而不包含根本身。

我会用reduce来做这件事,但仍然不能把我的头放在reduce和递归的结合上。有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-13 10:42:57

之后,您可以简单地使用map和平面数组。 .map(o => o.children).flat()

编辑:在找出真正的问题后更新的答案

尽管如此,您仍然可以使用map和平面逻辑,但可以使用递归方式。

代码语言:javascript
复制
function removeSingleChildElms (o) {
  if (!o.children) return

  if (o.children.length === 1) {
      return o.children.map(removeSingleChildElms).flat()
  } else {
    return o.children
  }
}

EDIT2:一些解释:问题是将对象数组转换为不同对象的数组。我不选择减少,因为问题并不关心兄弟元素之间的关系/逻辑。它只是关于转换,因此地图将工作得足够好。

该问题要求“跳过”带有一个子对象的对象。这是反复出现的部分,意思是:如果您看到一个满足此条件的对象,则需要进行更深层次的映射。在任何其他有效条件下,儿童保持不变(否则)

票数 0
EN

Stack Overflow用户

发布于 2019-03-13 14:37:55

可以通过将任务分解为两部分来简化树转换:

  1. 用于转换单个节点的函数
  2. 一个转换节点数组的函数。

要转换单个节点,我们编写transform1

  • 如果没有子节点,我们已经找到一个叶节点,返回单例节点。
  • 如果只有一个子节点,则删除节点并返回其唯一子节点的转换。
  • 否则,节点有多个子节点,调用第二个函数transformAll
代码语言:javascript
复制
const transform1 = ({ children = [], ...node }) =>
  children.length === 0         // leaf
    ? [ node ]
: children.length === 1         // singleton
    ? transform1 (...children)
: transformAll (children)       // default

为了转换一个节点数组,我们编写了transformAll -

代码语言:javascript
复制
const transformAll = (arr = []) =>
  arr .flatMap (transform1)

如您所见,transformAll调用transform1,后者也调用transformAll。这种技术被称为互递归,它是处理递归数据结构的一种很好的方法,就像您在问题中提出的那样。

为了确保我们的函数正常工作,我修改了树以包含更多的数据场景。注意,我们的程序适用于任何具有children属性的节点。所有其他属性都显示在结果中-

代码语言:javascript
复制
const data =
  [ { name: "a"
    , children:
        [ { name: "a.a"
          , children: 
              [ { name: "a.a.a"
                , children: []
                }
              , { name: "a.a.b"
                , foo: 123
                , children: []
                }
              ]
          }
        ]
    }
  , { name: "b"
    , children:
        [ { name: "b.a"
          , children: 
              [ { name: "b.a.a"
                , children: []
                }
              , { name: "b.a.b"
                , children: []
                }
              ]
          }
        , { name: "b.b"
          , children: []
          }
        ]
    }
  , { name: "c"
    , children: []
    }
  ]

我们可以对你的数据运行transformAll来转换所有的节点-

代码语言:javascript
复制
transformAll (data)
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]

或者转换一个节点,我们称之为transform1 -

代码语言:javascript
复制
transform1 (data[0])
// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// ]

transform1 (data[2])
// [ { name: 'c' } ]

展开下面的代码片段,在自己的浏览器中验证结果-

代码语言:javascript
复制
const data =
  [ { name: "a"
    , children:
        [ { name: "a.a"
          , children: 
              [ { name: "a.a.a"
                , children: []
                }
              , { name: "a.a.b"
                , foo: 123
                , children: []
                }
              ]
          }
        ]
    }
  , { name: "b"
    , children:
        [ { name: "b.a"
          , children: 
              [ { name: "b.a.a"
                , children: []
                }
              , { name: "b.a.b"
                , children: []
                }
              ]
          }
        , { name: "b.b"
          , children: []
          }
        ]
    }
  , { name: "c"
    , children: []
    }
  ]

const transform1 = ({ children = [], ...node }) =>
  children.length === 0         // leaf
    ? [ node ]
: children.length === 1         // singleton
    ? transform1 (...children)
: transformAll (children)       // default

const transformAll = (arr = []) =>
  arr .flatMap (transform1)

console .log (transformAll (data))

// [ { name: 'a.a.a' }
// , { name: 'a.a.b', foo: 123 }
// , { name: 'b.a.a' }
// , { name: 'b.a.b' }
// , { name: 'b.b' }
// , { name: 'c' }
// ]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55139385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档