2017-04-21 106 views
2

我有这样的数组:的Javascript嵌套数组元素得到

"pages": [{ 
    "key": "1", 
    "pages": [{ 
     "key": "2", 
     "pages": [{ 
      "key": "3" 
     }] 
    }, 
     { 
      "key": "4", 
      "pages": [{ 
       "key": "5" 
      }] 

     }] 
}] 

其中键1和4是在相同的水平和1包含2含有3和键4中包含5我想要的结果是在订单[3,2,5,1,4]。我已经尝试了以下递归,但我无法获得正确的顺序。

function fnGetAll (oTopDetailPage, array) { 
    var i; 

    for (i=0; i<oTopDetailPage.length; i++) { 
     array.push(oTopDetailPage[i]); 
     if(oTopDetailPage[i].pages) { 
      fnGetAllSubPages(oTopDetailPage[i].pages, array); 
     } 
    } 
    return array; 
} 
+1

你要为并没有真正意义的输出。你能改变你的期望吗?也许是一个包含父页面的对象,然后是像{{1:[2,3],4:[5]}}这样的子对象。为什么你需要输出你要求的? –

+0

如果在对象的“页面”属性中添加另一个页面,其中包含“6”的“关键字”,并且“键”为“1”,那么这些页面将落在输出中,为什么? –

+0

为什么'5'先于'1'? – julekgwa

回答

5

如果你想要一个Depth-first search,你可以先迭代孩子,然后把实际的密钥。

结果是一个数组,它与给定的数组有一点不同。

function getDepthFirst(object) { 
 
    var result = []; 
 
    object.pages.forEach(function iter(a) { 
 
     Array.isArray(a.pages) && a.pages.forEach(iter); 
 
     result.push(a.key); 
 
    }); 
 
    return result; 
 
} 
 

 
var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] }; 
 
    
 
console.log(getDepthFirst(data)); // [3, 2, 5, 4, 1]

补遗用于获取的[3, 5, 2, 4, 1]一个反向级顺序遍历结果,与一个临时数组,其从相同的水平收集所有数据,并从所有水平恢复的项目阵列,从最高到最低。

该回调函数在实际水平上使用闭包。

function getData(object) { 
 
    var temp = []; 
 
    object.pages.forEach(function iter(level) { 
 
     return function (a) { 
 
      Array.isArray(a.pages) && a.pages.forEach(iter(level + 1)); 
 
      temp[level] = temp[level] || []; 
 
      temp[level].push(a.key); 
 
     }; 
 
    }(0)); 
 
    return temp.reduceRight(function (r, a) { 
 
     return r.concat(a); 
 
    }); 
 
} 
 

 
var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] }; 
 

 
console.log(getData(data)); // [3, 5, 2, 4, 1]

+0

谢谢:) 是否可以像[3,5,2,4,1]后顺序遍历? – boomcode

+0

@boomcode,这是可能的。名称是*反转级别遍历*,请参阅编辑。 –

1

你的根容器是一点都不奇怪,因为它是无效的JavaScript。我假设它是{pages: ... }并附上{},但即使这样也没有意义,因为根容器不包含key属性。

你应该先解决您的节点,这样你有一个统一的结构,例如

type Node = Node { key: String, pages: [Node] } 

然后实现您的深度优先搜索是微不足道

const dfs = ({key, pages = []}) => 
 
    [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key] 
 
    
 
const data = { 
 
    "key": "1", 
 
    "pages": [{ 
 
     "key": "2", 
 
     "pages": [{ 
 
      "key": "3" 
 
     }] 
 
    }, 
 
    { 
 
     "key": "4", 
 
     "pages": [{ 
 
      "key": "5" 
 
     }] 
 
    }] 
 
} 
 
    
 
console.log(dfs(data)) 
 
// [ '3', '2', '5', '4', '1' ]


如果您正在通过-h构造数据而且,不要。相反,我建议你制作一个简单的构造函数来统一构建数据。因为现在每个节点都保证有keypages属性,所以我们可以删除dfspages = []的默认参数值。这比较好,因为我们可以避免任何可能试图容纳失踪财产的防御性编程。

const dfs = ({key, pages}) => 
 
    [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key] 
 
    
 

 
const makeNode = (key, ...pages) => ({key, pages}) 
 

 
const data = 
 
    makeNode('1', 
 
    makeNode('2', 
 
     makeNode('3')), 
 
    makeNode('4', 
 
     makeNode('5'))) 
 
    
 
console.log(dfs(data)) 
 
// [ '3', '2', '5', '4', '1' ]

+0

hm ... :)看起来更好一些。 –

+0

@NinaScholz <3 <3它只能工作,因为我强迫根节点包含一个'key'属性,否则调用我的函数会很奇怪。 – naomik