繁体   English   中英

递归函数的跟踪路径

[英]track path of recursive function

我正在尝试在json对象中跟踪深层嵌套值的路径,但很难获取路径。 每个项目都是对象数组,并且可以具有子项目。 如果对象c存在于json数据中,则它始终位于最后一个项目数组中。

item: [
{
    a:5,
    item: [
        {
            item: [
                {c:1},
                {x:4},
            ],
            ...
        },
        {},
        {}
    ]
},
{},
{}
]

const findPath = (items) => {
    let path = []

    items.forEach((item,i) => {
        if('item' in item){
            path = path.concat(findPath(item.item))
        }
        else if('c' in item) {
            path.push(i)
        }
    })
return path
}

如果我有3个具有不同项目深度的c对象,那么我将有:

[
  [0,0,0], //item[0].item[0].item[0].c
  [1,0], //item[1].item[0].c
  [4]] , //item[4].c

有什么帮助吗?

这里的主要问题是您不跟踪常见情况。 仅当找到叶子时才存储索引,但是您需要介于两者之间的所有步骤。 这是递归,您还必须随身携带返回值,否则最终会踩到它们。 这有效:

objects = [
    {},
    {
        item: [
            {},
            {},
            {
                a:5,
                item: [
                    {
                        item: [
                            {c:1},
                            {x:4},
                        ]
                    },
                    {},
                    {}
                ]
            },
            {}
        ]
    }
]

const findPath = (items, current_path, matching_paths) => {
    items.forEach((item,i) => {
        if('item' in item){
            current_path.push(i);
            current_path = current_path.concat( 
                findPath(item.item, current_path, matching_paths) 
            );
        }
        else if('c' in item) {
            current_path.push(i);
            matching_paths.push( current_path.slice() );
            current_path = [];
        }
    })
}

var path = [];
var paths = [];
findPath(objects, path, paths);
console.log(paths); //[[1, 2, 0, 0]]

如果找到C ,则将路径对象推送到路径数组,并为其余路径更新该路径对象。

const findPath = (items) => {

     let path = []

     items.forEach((item,i) => {

         if('item' in item){
             let item_path = findPath(item.item)

             if(item_path.length > 0){
                 item_path[0].path.push(i)
                 path.push(item_path[0]) 
             }
        }
        else if('c' in item){
            path.push({path:[i], c:item.c})
        }
     })
     return path
}

该函数必须是递归的,这意味着它应该使用不同的参数调用自身,而不是永远循环。 以下是您要寻找的东西。 我在TypeScript中创建了它以确保正确键入,但是只需删除所有类型定义,它就会变成JavaScript:

const trackPath: number[][] = [];
function findPath(topItem: any, path: number[], position: number): void
{
    const currentPath = path.slice();
    currentPath.push(position);
    const newTopItem = topItem['item'];
    if (Array.isArray(newTopItem)) {
        // here is the recursion for each subitem
        newTopItem.forEach((item, i) => findPath(item, currentPath, i));
    }
    if ('c' in topItem) {
        trackPath.push(currentPath);
    }
}

// this is the main method to call
function actuallyGetThePath(myTopItem: any): number[][] {
    findPath(myTopItem, [], 0);
    return trackPath;
}

祝好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM