这些是数组:
[ 'markdown',
[ 'para', 'this is a paragraph' ],
[ 'para', {class: 'custom-class'}, 'another paragraph' ],
[ 'hr' ],
[ 'bulletlist',
[ 'listitem', 'This is a list' ],
[ 'listitem', 'This is another list' ] ] ]
我想要做的是找到每个字符串中的最后一个字符串。在这种情况下,'this is a paragraph'
,'another paragraph'
,'This is a list'
,'This is another list'
。 (我对只有一个字符串的数组感兴趣,在这种情况下,hr
。但我猜这是另一个问题。)
我能做到的最好的就是:
for (i = 1; i < tree.length; i++) {
var node = tree[i]
var lastItem = node[node.length - 1]
console.log(lastItem)
}
\\ this is a paragraph
\\ {class: 'custom-class'}
\\ hr
\\ [ 'listitem', 'This is a list' ]
\\ [ 'listitem', 'This is another list' ]
我认为你可以看到问题,但是1)循环有时会找到一个嵌套的数组/对象2)它不是递归的。
我应该如何修改循环,以便始终找到这些数组的最后一个字符串?
答案 0 :(得分:2)
使用带累加器的reducer和递归:
var findLast = function(xs) {
return xs.reduce(function(acc, x) {
if (Array.isArray(x)) {
var last = x[x.length-1]
if (Array.isArray(last)) {
return acc.concat(findLast(x))
}
return acc.concat(last)
}
return acc
},[])
}
console.log(findLast(yourArray))
/*^
[ 'this is a paragraph',
'another paragraph',
'hr',
'This is a list',
'This is another list' ]
*/
请注意,递归不是必需的,因为递归问题总是可以使用循环和必要时的堆栈来解决。递归更优雅,但在JavaScript中,它会炸掉堆栈中的许多嵌套数组(直到浏览器发布TCO)但循环赢了:
var findLast = function(xs) {
var out = []
for (var i = 0; i < xs.length; i++) {
var x = xs[i]
if (Array.isArray(x)) {
var last = x[x.length-1]
if (Array.isArray(last)) {
xs = x
i = 0
} else {
out.push(last)
}
}
}
return out
}
这解决了您描述的一般问题,但如果您想要使用单个元素排除数组,则需要再添加一个条件:
if (Array.isArray(x) && x.length > 1) {
答案 1 :(得分:1)
我很难理解你的对象结构,所以我首先给出一个措辞的答案。如果您的对象结构变得更清晰,我可以编写一个实际的编码示例。
不可能这里很难不使用递归,因为你不知道数组嵌套的深度。您需要做的是创建一个接收对象作为参数的函数。然后,该函数遍历对象的所有元素,如果它看到它们中的任何一个是数组,则调用它自己。当它到达最后一个元素时,它会被打印出来。
基本上如下:
function findLastString(obj)
loop obj.length
if obj[i] == array
then findLastString(obj[i])
end loop
if obj[obj.length-1] != array
then print(obj[obj.length-1])
end function