How do I recursively use the reduce() method in javascript?

11,865

Reduce with a test for an array and a recursive call of the reduce function.

Edit: Kudos to Jonathan Lonowski for the hint.

function flat(r, a) {
    if (Array.isArray(a)) {
        return a.reduce(flat, r);
    }
    r.push(a);
    return r;
}

var array = [3, [4, [5, [6, 7]]]];
document.write('<pre>' + JSON.stringify(array.reduce(flat, []), 0, 4) + '</pre>');

Share:
11,865
Nikhil Prabhu
Author by

Nikhil Prabhu

Updated on July 18, 2022

Comments

  • Nikhil Prabhu
    Nikhil Prabhu almost 2 years

    The question is to use reduce() to operate on an array of arrays and return a homogeneous array with no sub-arrays. Eg - [1,2,[3,[4,5]]] will return [1,2,3,4,5].

    Here is code that works, considering the sub-array itself is not another array of arrays-

    var a = [3,[4,[5,[6,7]]]];
    var b = 8;
    var c = [9,10];
    var x = []
    
    var arr = [1,2,a,b,c];
    arr = [1,2,3,4,c];
    
    console.log(arr.reduce(function oneArray(a,b)
        {
            return a.concat(b); 
        },x))
    

    Notice that I change my arr array as the code does not work for the first arr array i.e [1,2,a,b,c]. For arr [1,2,3,4,c] the object returned is [1,2,3,4,9,10]

    Here is my attempt to make it work for the first arr-

    function oneArray(a,b)
        {
            if (typeof b == "object")
                b = b.reduce(oneArray(x,y),[]);
            return a.concat(b); 
        }
    
        console.log(arr.reduce(oneArray(a,b),x));
    

    This gives me the error

    Uncaught TypeError: [object Array] is not a function(anonymous function) @ Flattening.html:27

    It interprets my function oneArray as an array not a function

    I understand the problem comes from the fact that reduce can (I think) work only with a function defined as a parameter. Does anyone have a solution so that I get [1,2,3,4,5,6,78,9,10] as my result working around the limitations of reduce() unless I missed something?

    • Stephan Bijzitter
      Stephan Bijzitter over 8 years
      I have only read the title, but in the title you're asking the wrong question. You have situation A and you want to get to situation B. Explain what you want; not how you think you want it. If you knew how, you would not have to ask a question.
    • Jonathan Lonowski
      Jonathan Lonowski over 8 years
      To provide a function as an argument, pass it by name alone – arr.reduce(onArray, x). Including parenthesis after the name invokes the function first and provides its return value to arr.reduce().
    • Dmitri Pavlutin
      Dmitri Pavlutin over 8 years
      Why duplication? Here is required recursion, in the other question are just 2 level arrays.
  • Jonathan Lonowski
    Jonathan Lonowski over 8 years
    Note: The line for reducing embedded arrays could be shortened to return a.reduce(flat, r);. It'll .push() to the same array throughout the call stack vs. creating a new array to concat.
  • Nina Scholz
    Nina Scholz over 8 years
    @JonathanLonowski, thank you, pl see edit.