Typescript: recursive check nestest arrays

情到浓时终转凉″ 提交于 2020-01-16 14:04:12

问题


i have problem looping through a nested array that can contains arrays of itself... that should represent a dynamic menu as follow:

this is how the objects are made:

Interface IMenuNode:

export interface IMenuNode {
    title: string;
    haveChildren: boolean;
    id: string;
    node: Array<IMenuNode>;
    link: string;
    img: string;
    value: string;
}

Class DataNode that implements IMenuNode

export class DataNode implements IMenuNode {
    title: string;
    haveChildren: boolean;
    id: string;
    node: Array<IMenuNode>;
    link: string;
    img: string;
    value: string;


userMenu: Array<IMenuNode>;

Now i have some informations in the MenuData as follow:

const MenuData: Array<IMenuNode> =
    [
        new DataNode('Menu 1', true, 'menu1', [
            new DataNode('SubMenu 1', true, 'submenu1',[
                new DataNode('SubSubMenu1', false ,'subsubmenu1', null, "/", "pathSelectorIcon.png"),
                new DataNode('SubSubmenu2', false, 'subsubmenu2', null ,"/", "pathSelectorIcon.png"),
            ]),
            new DataNode('Menu 2', true, 'menu2', [
            new DataNode('SubMenu 1', true, 'submenu1',[
                new DataNode('SubSubMenu1', false ,'subsubmenu1', null, "/", "pathSelectorIcon.png"),
                new DataNode('SubSubmenu2', false, 'subsubmenu2', null ,"/", "pathSelectorIcon.png"),
            ]),

How can i loop the entire MenuData (even recursively) and dynamically build a new menu (userMenu) based on some conditions to choose which items (menu and submenu) the new menu should have of?


回答1:


The function below apparently do what you expect, hope it helps.

userMenu = newUserMenu(MenuData);

function newUserMenu(original: Array<IMenuNode>): Array<IMenuNode> {
    const newMenu: Array<IMenuNode> = []
    for (let menu of original) {
        if (User.hasAccess(menu)) { // Or other conditions

            // To ensure new reference
            // Note not passing the children, it must pass through recursive method below
            const newNode = new DataNode(menu.title, menu.haveChildren, menu.id, null, menu.link, menu.img, menu.value);
            newMenu.push(newNode);
            if (newNode.haveChildren) {
                newNode.node = newUserMenu(menu.node);
            }
        }
    }
    return newMenu;
} 

I've edited your class and interface too, to ensure that the construction works like the example.

interface IMenuNode {
    title: string;
    haveChildren: boolean;
    id: string;
    node?: Array<IMenuNode>;
    link?: string;
    img?: string;
    value?: string;
}

class DataNode implements IMenuNode {

    constructor(
        public title: string,
        public haveChildren: boolean,
        public id: string,
        public node?: Array<IMenuNode>,
        public link?: string,
        public img?: string,
        public value?: string,
    ) { }
}

Edit: new example validating the children before adding current level on new menu.

// The new function only add the "dir" menus if they have children where the user have access
function newUserMenu2(original: Array<IMenuNode>): Array<IMenuNode> {
    const newMenu: Array<IMenuNode> = [];
    for (let menu of original) {
        if (User.hasAccess(menu)) {// Or other conditions
            // To ensure new reference
            // Note not passing the children, it must pass through recursive method below
            const newNode = new DataNode(menu.title, menu.haveChildren, menu.id, null, menu.link, menu.img, menu.value);
            if (newNode.haveChildren) {
                newNode.node = newUserMenu2(menu.node);
            }
            // Note, only add the menu if it has a link or if it "stores" a menu that the user has access and that has a link
            if (Array.isArray(newNode.node) && newNode.node.length > 0 || newNode.link) {
                newMenu.push(newNode);
            }
        }
    }
    return newMenu;
}


来源:https://stackoverflow.com/questions/58838567/typescript-recursive-check-nestest-arrays

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!