代码之家  ›  专栏  ›  技术社区  ›  dbzx10299

javascript中递归转换对象和嵌套对象

  •  0
  • dbzx10299  · 技术社区  · 10 月前

    如何通过移除所有对象来递归转换以下对象(包括嵌套对象) edges nodes ? 请注意,结构始终相同,这意味着边将始终是一个节点阵列。

    const data = {
      products: {
        edges: [
          {
            node: {
              title: 'x',
              collections: {
                edges: [
                  {
                    node: {
                      title: 'x - collection'
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
    

    我有一个助手功能 removeEdgesAndNodes

    function removeEdgesAndNodes(obj) {
      return obj.edges.map(edge => edge?.node)
    }
    
    removeEdgesAndNodes(data.products)
    

    预期输出

    [
      {
        title: 'x',
        collections: [
          {
            title: 'x-collection'
          }
        ]
      }
    ]
    

    注释 查询嵌套得更远并不罕见,尽管它通常不会超过三个级别。

    对于任何列表,模式总是相同的。例如 images 后面跟着 边缘 然后 node 其包含每个图像的属性。

    const data = {
      products: {
        edges: [
          {
            node: {
              title: 'x',
              collections: {
                edges: [
                  {
                    node: {
                      title: 'x - collection',
                      products: {
                        edges: [
                          {
                            node: {
                              title: 'product in x collection'
                            }
                          }
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
    
    1 回复  |  直到 10 月前
        1
  •  2
  •   Nick Parsons Felix Kling    10 月前

    在您的 .map() 方法,你可以 destructure 要拉出的当前对象 node / collections 属性(在没有 collection 名为的新对象中的属性 rest ,在您的示例中,这只是一个具有 title ,但如果你有更多的属性,它也会包括这些)。然后你可以将其扩散到你的新对象中。然后,您可以选择添加 收藏 属性添加到使用对象属性排列创建的新对象 ... 如果当前对象具有 收藏 属性使用 ...(collections && {collections: removeEdgesAndNodes(collections)}) ,如果 收藏 undefined (因为它在你最内部的对象中),或者它会添加 收藏 属性映射到当前对象,通过递归调用您的 removeEdgesAndNodes 用于处理内部对象的函数:

    const data = { products: { edges: [ { node: { title: 'x', collections: { edges: [ { node: { title: 'x - collection' } } ] } } } ] } }
    
    function removeEdgesAndNodes(obj) {
      return obj.edges.map(({node: {collections, ...rest}}) => ({
        ...rest,
        ...(collections && {collections: removeEdgesAndNodes(collections)})
      }))
    }
    
    console.log(removeEdgesAndNodes(data.products));

    您可以使用 for 循环和if语句,您可能会发现它们更可读:

    const data = { products: { edges: [ { node: { title: 'x', collections: { edges: [ { node: { title: 'x - collection' } } ] } } } ] } };
    
    function removeEdgesAndNodes(obj) {
      const res = [];
      for (const { node } of obj.edges) {
        const { collections, ...rest } = node;
        if (collections)
          res.push({...rest, collections: removeEdgesAndNodes(collections)});
        else
          res.push(rest);
      }
      
      return res;
    }
    
    console.log(removeEdgesAndNodes(data.products));

    要处理动态嵌套对象属性键,一种方法是重构每个对象。对于每个 key value 在函数的输入对象中,可以检查value属性中的 edges 所有物如果它具有边属性,则可以映射该属性以删除动态属性名称(例如: 收藏 / products )通过递归地重建该对象:

    const data = { products: { edges: [ { node: { title: 'x', collections: { edges: [ { node: { title: 'x - collection', products: { edges: [ { node: { title: 'product in x collection' } } ] } } } ] } } } ] } }
    
    function removeEdgesAndNodes(obj) {
      return Object.fromEntries(Object.entries(obj).map(([key, val]) => [
        key,
        val.edges?.map(({node}) => removeEdgesAndNodes(node)) ?? val
      ]));
    }
    
    console.log(removeEdgesAndNodes(data));