簡體   English   中英

如何構建遞歸函數

[英]How to build a recursive function

關於遞歸函數有一些問題,我無法理解,想知道是否可以得到一些幫助。

我有一個像下面這樣的json對象

const data = {
    "navItems": [
        {
            "type": "directory",
            "name": "Nav Title 1",
            "children": [
                {
                    "downloadUrl": "",
                    "content": "",
                    "type": "file",
                    "name": "File 1.pdf"
                },
                {
                    "downloadUrl": "",
                    "content": "",
                    "type": "file",
                    "name": "File 2.pdf"
                },
                {
                    "type": "directory",
                    "name": "Sub Title 1",
                    "children": [
                        {
                            "downloadUrl": "",
                            "content": "",
                            "type": "file",
                            "name": "Sub File 1.pdf"
                        },
                        {
                            "downloadUrl": "",
                            "content": "",
                            "type": "file",
                            "name": "Sub File 2.docx"
                        }
                    ]
                },
                {
                    "type": "directory",
                    "name": "Sub Title 2",
                    "children": [
                        {
                            "type": "directory",
                            "name": "Sub Sub Title 1",
                            "children": [
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "type": "file",
                                    "name": "Sub Sub File 1.pdf"
                                },
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "type": "file",
                                    "name": "Sub Sub File 2.pdf"
                                }
                            ]
                        },
                        {
                            "type": "directory",
                            "name": "Sub Sub Title 2",
                            "children": [
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "type": "file",
                                    "name": "Sub Sub File 1.pdf"
                                },
                                {
                                    "downloadUrl": "",
                                    "content": "",
                                    "type": "file",
                                    "name": "Sub Sub File 2.pdf"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

我需要動態創建一個導航菜單,以像這樣的方式對這個數據集做出反應

let newNavItem = {
    id: 'apps.' + id,
    title: item.name,
    type: 'collapse',
    icon: 'heroicons-outline:folder',
    children: [
      {
         id: 'paper.' + sub2item.name,
         title: sub2item.name,
         type: 'item',
         url: sub2item.downloadUrl,
      }
    ]
  }

可折疊導航項的示例(類型 = 目錄)

 {
    id: id,
    title: title,
    type: 'collapse',
    icon: 'heroicons-outline:folder',
    children: []
  }

將進入 children 數組的可點擊 URL 示例:(type = File)


{
   id: id,
   title: name,
   type: 'item',
   url: url,
}

編輯:這是我目前使用該功能的地方。

const buildNavBlock = (navItem) => {
        if (navItem.hasOwnProperty("children") && navItem.children.length > 0 && navItem.type == "directory") {
      console.log(navItem.children);
        return {
              id: 'apps.' + navItem.name,
              title: navItem.name,
              type: 'collapse',
              icon: 'heroicons-outline:folder',
              children: buildNavBlock(navItem.children)
      }
    } else {
       return {
         id: 'paper.' + navItem.name,
         title: navItem.name,
         type: 'item',
         url: 'apps/documents/',
       }
    }
};

data.navItems.forEach((item => {
  let nav = buildNavBlock(item);
  console.log(nav);
}))

似乎當您調用遞歸函數時,您並沒有為每個孩子調用它。 將其更改為此可能會有所幫助:

const buildNavBlock = (navItem) => {
        if (navItem.hasOwnProperty("children") && navItem.children.length > 0 && navItem.type == "directory") {
      console.log(navItem.children);
        return {
              id: 'apps.' + navItem.name,
              title: navItem.name,
              type: 'collapse',
              icon: 'heroicons-outline:folder',
              children: navItem.children.map(child => buildNavBlock(child))
      }
    } else {
       return {
         id: 'paper.' + navItem.name,
         title: navItem.name,
         type: 'item',
         url: 'apps/documents/',
       }
    }
};

data.navItems.forEach((item => {
  let nav = buildNavBlock(item);
  console.log(nav);
}))

這可能會有所幫助

 const data = { "navItems": [ { "type": "directory", "name": "Nav Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "File 2.pdf" }, { "type": "directory", "name": "Sub Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub File 2.docx" } ] }, { "type": "directory", "name": "Sub Title 2", "children": [ { "type": "directory", "name": "Sub Sub Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 2.pdf" } ] }, { "type": "directory", "name": "Sub Sub Title 2", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 2.pdf" } ] } ] } ] } ] } /*let newNavItem = { id: 'apps.' + id, title: item.name, type: 'collapse', icon: 'heroicons-outline:folder', children: [ { id: 'paper.' + sub2item.name, title: sub2item.name, type: 'item', url: sub2item.downloadUrl, } ] }*/ const {useEffect, useState} = React const Dir=({data, isActive=true, collapsed=true})=>{ const [active,setActive]=useState(!collapsed) return <li className={"dir "+(isActive ? "active":"nested")} href=""> {data.title} <span className={"caret "+(active?"caret-down":"")} onClick={()=>setActive(v=>!v)}/> <ul> {(data.children || []).map(v=>v.type==="collapse"? <Dir key={v.id} data={v} isActive={active}/>:<File key={v.id} data={v} isActive={active}/>)} </ul> </li> } const File=({data,isActive})=>{ return <li className={"file "+(isActive ? "active":"nested")} href={data.url}> {data.title}</li> } const App=(props)=>{ const makeNav=(data)=> (data.type === "directory")? { id: 'paper.' + data.name, title: data.name, type: 'collapse', icon: 'heroicons-outline:folder', children: (data.children||[]).map(v=>makeNav(v)) }:(data.type === "file")? { id: 'paper.' + data.name, title: data.name, type: 'item', url: data.downloadUrl, }:"" const [nav, setNav]=useState([]) useEffect(()=>{ let v=props.data.navItems.map(v=>makeNav(v)) setNav(v) //console.log(v) },[]) return <div class="sidebar"> <ul> {nav.map(v=>v.type==="collapse"? <Dir key={v.id} data={v}/>:<File key={v.id} data={v}/>)} </ul> </div> } ReactDOM.render(<App data={data}/>,document.getElementById('app'))
 /* Style sidebar links */ .sidebar li { padding: 6px 8px 6px 16px; text-decoration: none; font-size: 20px; color: #818181; } /* Style links on mouse-over */ .sidebar li:hover { color: #f1f1f1; } .caret { cursor: pointer; user-select: none; /* Prevent text selection */ } /* Create the caret/arrow with a unicode, and style it */ .caret::before { content: "\25B6"; color: black; display: inline-block; margin-right: 6px; } /* Rotate the caret/arrow icon when clicked on (using JavaScript) */ .caret-down::before { transform: rotate(90deg); } /* Hide the nested list */ .nested { display: none; } /* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */ .active { display: block; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> <div id="app"> </div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM