How can recursion be used in JavaScript to find the longest string within a nested array?

After reviewing multiple solutions for finding the longest string in an array, I encountered a new challenge. I am now trying to find the longest string within a nested array. The nesting levels can vary from N-levels deep to just two levels deep. My initial solution is outlined below:

    let myArray = [
    'ABC',
    'ABCD',
    'ABCDE',
    [
      'ABC',
      'ABCABABA',
      [
        'ABABABABABABABABAZZ'
      ],
    'ABCABABASS',

     ],
   'ABCDEFGH',
   'ABABABABZZQ'
   ]

function longestString(arr) {
let longestStr = ''
arr.forEach(item => {
if(typeof item === 'string') {
  if(item.length > longestStr.length) {
    longestStr = item;
    console.log('Longest Item', item);
  }    
} else {
    longestString(item)
  }
})
 return longestStr;
}

console.log(longestString(myArray))

Current Output -> ABABABABZZQ

Desired Output -> 'ABABABABABABABABAZZ'

What adjustment is necessary to only display the longest string?

Answer №1

To get the desired output from the recursive call, it is important to utilize the return value effectively. Take the string returned by the recursive call and compare it against the item in the same way you compared them previously. If the returned string is longer than longestStr, update longestStr with this new value:

let myArray = [
  'ABC',
  'ABCD',
  'ABCDE', [
    'ABC',
    'ABCABABA', [
      'ABABABABABABABABAZZ'
    ],
    'ABCABABASS',

  ],
  'ABCDEFGH',
  'ABABABABZZQ'
]

function longestString(arr) {
  let longestStr = ''
  arr.forEach(item => {
    if (typeof item === 'string') {
      if (item.length > longestStr.length) {
        longestStr = item;
      }
    } else {
      const nestedLongest = longestString(item);
      if (nestedLongest.length > longestStr.length) {
        longestStr = nestedLongest;
      }
    }
  })
  return longestStr;
}

console.log(longestString(myArray))

In a more concise approach, you can avoid repetition by utilizing a helper function for comparison:

const myArray=['ABC','ABCD','ABCDE',['ABC','ABCABABA',['ABABABABABABABABAZZ'],'ABCABABASS',],'ABCDEFGH','ABABABABZZQ']

function longestString(arr) {
  let longestStr = '';
  const check = str => {
    if (str.length > longestStr.length) longestStr = str;
  };
  arr.forEach(item => {
    check(typeof item === 'string' ? item : longestString(item));
  });
  return longestStr;
}

console.log(longestString(myArray))

Another approach involves using an inner function that maintains a persistent longestStr variable throughout the scope of the longestString function. This eliminates the need to handle recursive call results separately:

const myArray=['ABC','ABCD','ABCDE',['ABC','ABCABABA',['ABABABABABABABABAZZ'],'ABCABABASS',],'ABCDEFGH','ABABABABZZQ']

function longestString(input) {
  let longestStr = '';
  const check = str => {
    if (str.length > longestStr.length) longestStr = str;
  };
  function recursiveFn(arr) {
    arr.forEach((item) => {
      if (typeof item === 'string') check(item)
      else recursiveFn(item);
    });
  }
  recursiveFn(input);
  return longestStr;
}

console.log(longestString(myArray))

Answer №2

Utilize the Array.flat() method to flatten out the array, followed by using Array.reduce() to determine the longest item:

const myArray = [
  'ABC',
  'ABCD',
  'ABCDE', [
    'ABC',
    'ABCABABA', [
      'ABABABABABABABABAZZ'
    ],
    'ABCABABASS',

  ],
  'ABCDEFGH',
  'ABABABABZZQ'
]

const result = myArray
  .flat(Infinity)
  .reduce((r, s) => s.length > r.length ? s : r);
  
console.log(result);

Answer №3

You have the ability to achieve this using just one reduce method

const myArray = [
  'ABC',
  'ABCD',
  'ABCDE', [
    'ABC',
    'ABCABABA', [
      'ABABABABABABABABAZZ'
    ],
    'ABCABABASS',

  ],
  'ABCDEFGH',
  'ABABABABZZQ'
];

const findLongestString = array => array.reduce((result, item) => typeof item === 'string' ? item.length > result ? item : result : findLongestString(item), '');
  
console.log(findLongestString(myArray));

Answer №4

To start, make sure you declare the variable longestStr outside of the function. Additionally, remember to use the return keyword.

return longestString(item)

let myArray = [['ABC','ABCD','ABCDE',
    ['ABC','ABCABABA',
    ['ABABABABABABABABAZZ'],
    'ABCABABASS'],
   'ABCDEFGH',
   'ABABABABZZQ']]
   
let longestStr = ''
function longestString(arr) {
  arr.forEach(item => {
    if(typeof item === 'string') {
      if(item.length > longestStr.length) {
        longestStr = item;
        console.log('Longest Item', item);
      }    
      } else {
        return longestString(item)
      }
  });
  return longestStr;
}

console.log(longestString(myArray));

UPDATE - You can now pass the parameter longestStr to the longestString function

let myArray = [['ABC','ABCD','ABCDE',
    ['ABC','ABCABABA',
    ['ABABABABABABABABAZZ'],
    'ABCABABASS'],
   'ABCDEFGH',
   'ABABABABZZQ']]

function longestString(arr,longestStr) {
  arr.forEach(item => {
    if(typeof item === 'string') {
      if(item.length > longestStr.length) {
        longestStr = item;
        console.log('Longest Item', item);
      }    
      } else {
        var value = longestString(item,longestStr);
        if(value.length > longestStr.length){
           longestStr = value;
        }
        return longestStr;
      }
  });
  return longestStr;
}

console.log(longestString(myArray,''));

Answer №5

By utilizing recursive calls, the function findLongestStr can determine the longest string within an input array while keeping track of the current maximum value.

let myArray = [
    'ABC',
    'ABCD',
    'ABCDE',
    [
      'ABC',
      'ABCABABA',
      [
        'ABABABABABABABABAZZ'
      ],
    'ABCABABASS',

     ],
   'ABCDEFGH',
   'ABABABABZZQ'
   ];

function findLongestStr(input){
  return input.reduce(function(o,i){
     if(i.constructor === Array){
        var value = findLongestStr(i);
        console.log("value array => ",value);
        if(o.length < value.length){
          o = value;
        }
     }else{
           console.log("value i => ",i);
        if(o.length < i.length){
          o = i;
        }
     }
     return o;
  },"");
}

console.log("max length => ",findLongestStr(myArray));

To see this code in action, refer to the jsFiddle demo - https://jsfiddle.net/k4yo35hb/1/

Answer №6

Your code has a key issue where the variable longestStr is redefined every time the recursive function is called, preventing you from comparing the longest string from each recursive call effectively.

One solution is to utilize the reduce() method, which is perfect for finding the maximum value in a regular un-nested array. By incorporating some recursion and still using reduce(), you can maintain state between recursions as all the recursive calls unwind within the reduce function:

let myArray = ['ABC','ABCD','ABCDE',['ABC','ABCABABA',['ABABABABABABABABAZZ'],'ABCABABASS',],'ABCDEFGH','ABABABABZZQ']


function longestString(arr) {
  return arr.reduce((longest, item) => {
    if (Array.isArray(item)) {
      let rec = longestString(item)
      if (rec.length > longest.length) longest = rec
    } else if (item.length > longest.length) longest = item;

    return longest
  }, '')
}

console.log(longestString(myArray))

Answer №7

In reference to @Adrian Brand's detailed response, the following is the proposed solution:

function getMaxStringLengthInArray(arr, initialMax = '') {
    return arr.reduce((currentMax, item) => {
        if (typeof item === 'string') {
            return item.length > currentMax.length ? item : currentMax;
        } else {
            return getMaxStringLengthInArray(item, currentMax);
        }
    }, initialMax);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Angular Promise ($q) functionality being non-operational

I am currently experimenting with integrating Angular and SignalR in a demo application. I have attempted to implement promises using the $q service, but for some reason my code is not functioning as expected. SERVICE var boardConsole = $.connection.buil ...

Having trouble getting multiple OR conditions in a PHP if() statement to work correctly. I've checked the array values and everything seems fine. Any idea what I

My if statement was working perfectly fine until I decided to add two additional || (or) operators. This is the snippet of code that's causing me trouble: if ($planDetails['Company']['name'] != 'company1' || $planDetail ...

Change the size of Jive Addon Tile in a vertical orientation

Seeking assistance with resizing the tile container in an angular application embedded within a Jive tile when the view changes. Any advice on how to tackle this issue? This particular tile is deployed to a Jive Cloud instance using a Jive add-on. ...

Creating a personalized router with Nuxt

Currently, I am working on setting up a custom route in Nuxt using the following nuxt.config.js: router: { base: '/', router: { extendRoutes (routes, resolve) { routes.push({ name: 'custom', pa ...

Triggering a Bootstrap 5 dropdown through code is only effective within the browser's developer console, rather than standard JavaScript implementation

I attempted to display a Bootstrap5 dropdown by clicking on a link in my web application. Despite trying various methods, such as dispatching events and utilizing the bootstrap Dropdown classes, I was unable to achieve success. Interestingly, both approach ...

Issue found in React Js test - TypeError: source.on does not exist as a function

I'm encountering an issue with my post request using multipart/form-data. Everything runs smoothly, except for the tests which are failing. When running the tests, I encounter an error message: TypeError: source.on is not a function. This is the code ...

Utilizing Vue.js with Electron: Establishing seamless data synchronization between backend and frontend

I am currently developing a Vue-Electron application. Picture a settings page on the frontend where users can adjust various variables. It is crucial for me to ensure that all settings are saved even when the settings page is reloaded. To achieve this, I r ...

Steps to find the First Non Repeating Character in a PHP string

What is the best way to find the first non-repeating character in a String using PHP? Consider the following example: $string = "ABBGAACCE"; $string_array = str_split($string); $temp_array = []; foreach($string_array as $key => $value) { if(array ...

What could be causing this if statement to fail in verifying if a specific number is present within an array?

Can you solve this challenge without using loops? The task is to create a function that takes an integer array of length 2 and returns True if it contains a 2 or a 3. Most test cases succeed, but some are failing. Here are the failing test cases: has23([ ...

Issue with AngularJS directive: Isolated scope preventing values from being inserted into template

After setting up the directive below: angular.module('news.directives', []) .directive('newsArticle', function($location, $timeout) { return { restrict: 'AE', replace: 'true&apo ...

ES6 Conditional Import and Export: Leveraging the Power of Conditional

Looking to implement a nested if else statement for importing and exporting in ES6? In this scenario, we have 2 files - production.js and development.js which contain keys for development and production code respectively. Additionally, there is another fil ...

Toggle switch with active state

I'm currently using Ionic 2 alongside Angular 2 beta 11. Is there a way to turn off the toggle switch? The Ionic documentation suggests using the checked attribute, but I've tried that and also attempted ng-checked with no luck. Any advice on t ...

Executing a server-side Java function from client-side JavaScript or jQuery on a JSP page

My JSP file has a dropdown list where I can select different entity kinds. Upon selecting an entity kind, I want to populate another dropdown list with the field names associated with that entity kind. This requires calling a JavaScript function when chang ...

The Electron application is experiencing difficulties locating the module at /resources/app/index.js

Just started my journey with electron and successfully created my first electron application. It runs perfectly fine with npm start, but I encounter issues when trying to execute it with npm run. (I am using Ubuntu Linux). The command line interface displa ...

What steps can I take to create a form supported by MobX that allows for instant propagation of changes and includes an undo

After browsing through various resources, I stumbled upon a similar query on this forum, but there's a twist to my situation. In my scenario, I have a model comprising a list of items with a field named selectedItem. This field can either be null or ...

Fetching dynamic JavaScript generated by PHP

I am creating a lightweight website and I have a piece of javascript code that I want to convert into a module by putting it in a separate file. This way, the code will only be loaded after a specific onClick event occurs. Successfully loading the javascr ...

Retrieve a specific string from the initial elements of the array

You're given an array: arr = ['Get your face right in there.', 'You&#8217;re like, wait, though, isn&#8217;t that too close? PUH-LEEZ. You and I both know that a person can never be too close to those browned lasagna edges that ...

How to Create a Custom Callback Function for jQuery's .html

I am currently working with the following code: $.ajax({ type: 'GET', url: 'index.php?route=checkout/onepagecheckout/getpaypaldata', dataType: 'json', success: function(json) { ...

Is the execution of renderer.render() synchronous or asynchronous?

In my quest to capture a screenshot after each rendered frame, I have noticed some duplicates. This has led me to suspect that I may be saving the screenshot before the rendering process is fully completed. Therefore... Is it possible for renderer.rend ...

Calculate the total of the smallest values in three columns as they are updated in real-time

I'm facing an issue with dynamically adding the sum of the 3 lowest values entered in columns. The Total Cost Field is not displaying any value, and changing the type from number to text results in showing NaN. I've tried various approaches but h ...