21834

Recursive function to stop when n-th nested array has no more nested arrays

Question:

I have JSON document which has some nested arrays. And I want to make function AAA() which recalls every time if an array has nested array. And then stop when there isn't more nested arrays.

For example. If I have:

array[AAA,BBB,CCC] | AAA[AAA,BBB,CCC] | AAA[AAA,BBB,CCC] | etc.

I want to call function AAA() always when AAA has a subarray. Let's say AAA has 5 times subAAA. I want the function(AAA) to call itself 5 times and then stop. And if in future I add more subarrays to call more times.

If it will help here is my .json:

{ "navigation" : [ { "name" : "home", "href" : "home.html" }, { "name" : "services", "href" : "interior.html", "navigation" : [ { "name" : "PROJECT MANAGEMENT", "href" : "interior.html", "navigation" : [ { "name" : "PROJECT MANAGEMENT", "href" : "interior.html" }, { "name" : "BUSINESS ANALYST", "href" : "interior.html" } ] }, { "name" : "BUSINESS ANALYST", "href" : "interior.html" } ] }, { "name" : "company", "href" : "home.html" } ] }

And the js code is:

function parseJSON(){ var navigation = new_json['navigation']; var nav_html = ''; for (var i = 0; i < navigation.length; i++) { var name = navigation[i]['name']; var href = navigation[i]['href']; var submenu = navigation[i]['navigation']; nav_html += '<li><a href="' + href + '">' + name + '<span class="ddArrow"></span></a>'; if( typeof(submenu) != 'undefined' ){ nav_html += '<ul>'; for( var j=0; j<submenu.length; j++ ){ var submenu_name = submenu[j]['name']; var submenu_href = submenu[j]['href']; nav_html += '<li><a href="' + submenu_href + '">' + submenu_name + '</a></li>'; } nav_html += '</ul>'; } nav_html += '</li>'; console.log( nav_html ); $('#navigation ul').html( nav_html ); }; };

That way I want to create navigation which has submenus. Now I have 3 levels, but if I decide to add 4th and 5th. I want my code to parse them in the HTML without writing more code. I have the rest ... I just need to the IF when function stops.

I simply don't write what I have tried because I understand why is not working.

Answer1:

A recursive function is quite simple to build, and is very similar to the code you already have:

function parseJSON() { function makeList(navigation) { var nav_html = ''; for (var i = 0; i < navigation.length; i++) { var name = navigation[i]['name'], href = navigation[i]['href'], submenu = navigation[i]['navigation']; nav_html += '<li><a href="' + href + '">' + name + '<span class="ddArrow"></span></a>'; if( typeof(submenu) != 'undefined' ){ nav_html += '<ul>'; // now here, do not iterate it again! // call the function recursively! nav_html += makeList(submenu); nav_html += '</ul>'; } nav_html += '</li>'; } return nav_html; } $('#navigation ul').html( makeList( new_json['navigation'] ) ); }

Answer2:

If I'm right in thinking that it only needs to run again if it contains a navigation property, you could just use:

// Without using Array.forEach. Array.isArray polyfill may be // required to support older browsers. function getLinks(obj) { var i, len; if (Array.isArray(obj.navigation)) { len = obj.navigation.length; for (i = 0; i < len; i += 1) { getLinks(obj.navigation[i]); } } } // Using Array.forEach - Polyfill may be required using the // forEach method to support older browsers. function getLinks(obj) { if (Array.isArray(obj.navigation)) { obj.navigation.forEach(function (link) { getLinks(link); }); } } // Array.isArray polyfill. if(!Array.isArray) { Array.isArray = function (vArg) { return Object.prototype.toString.call(vArg) === "[object Array]"; }; } // Array.forEach polyfill. if (!Array.prototype.forEach) { Array.prototype.forEach = function(fn, scope) { for(var i = 0, len = this.length; i < len; ++i) { fn.call(scope, this[i], i, this); } } }

<a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/isArray" rel="nofollow">isArray polyfill</a><br /><a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach" rel="nofollow">forEach polyfill</a>

Recommend

  • How do I convert a multi dimensional JSON object into javascript array
  • Swift POST Request in same Thread
  • jQuery Datatable: pagination and filter not display correctly
  • autoscroll of text and scrollbar in python text box
  • How do I retrieve Google Calendar Resources for my company using the PHP API client?
  • Copy paste data from one sheet to any other worksheet
  • boost::graph compilation issue with dynamic_properties and write_graphviz
  • self-reflexive n:m relation using composite keys in nhibernate
  • Check all CheckBoxes in GridView
  • Regex: Match desired chars at the beginning/end of string
  • How to execute two asynchronous functions sequentially
  • How to append distinct records from one table to another
  • Old parking page info is mixed in with search results for a newly crawled site
  • Set value of selected in dropdown in Angular 2
  • How can I enforce uniqueness rules that include more than one table?
  • Swagger/Swashbuckle list acceptable values?
  • Instead of adding another element It is landing to a another page
  • Number of variables doesn't match number of parameters - Yes they do
  • How do I clone a class in intellij?
  • Grails redirect with reverse proxy
  • Write “NOT IN” in Doctrine Query Language
  • Giving security priviliege to a scheduler in Java EE 6
  • Encrypting credit card details using AngularJS in Braintree
  • Autohotkey script running program with command line arguments
  • Command line installation of Code Signing certificates, .p12 files, and mobileprovisions
  • Eclipse MTJ doesn't see Java ME SDK 3.0 devices
  • Jenkins: FATAL: Could not initialize class hudson.util.ProcessTree$UnixReflection
  • Switching to Release Build causes runtime error in Web Reference
  • req.body is undefined - nodejs
  • Modifying destination and filename of gulp-svg-sprite
  • Importing jscolor library in angular 2
  • QuartzCore.framework for Mono Develop
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Acquiring multiple attributes from .xml file in c#
  • using HTMLImports.whenReady not working in chrome
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Authorize attributes not working in MVC 4
  • How can I remove ASP.NET Designer.cs files?
  • EntityFramework adding new object to nested object collection
  • java string with new operator and a literal