Filter Multidimensional Array in JavaScript

Given multiple dimensional arrays, create a filter function that takes a callback function as input and returns a new array with all elements that have passed the test implemented in the callback function.

Example

Input:
const arr = [[1, [2, [3, 'foo', {'a': 1, 'b': 2}]], 'bar']];
const filtered = arr.multiFilter((e) => typeof e === 'string');
console.log(filtered);

Output:
[[[["foo"]],"bar"]]

To filter a multi-dimensional array, we will have to filter each sub-array recursively and merge their results.

const filter = (arr, test) => {
    // Store the output
    const result = [];

    //iterate the array
    for (let a of arr) {
        //if sub-array
        if (Array.isArray(a)) {
            //recursively filter the sub-array
            const output = filter(a, test);

            //store the result
            result.push(output);
        } else {
            //if not an array
            //test the element
            //if it passes the test, store its result
            if (test(a)) {
            result.push(a);
            }
        }
    }

    //return the result
    return result;
};

We had already seen how to create the polyfill for the filter of a one-dimensional array.

In a similar fashion, we will extend Array’s prototype and add a new method multiFilter that will take a callback function and filter the array based on the callback’s result.

Array.prototype.multiFilter = function (test) {

    //original array;
    const originalArray = this;

    const filter = (arr, test) => {
        // Store the output
        const result = [];

        //iterate the array
        for (let a of arr) {
            //if sub-array
            if (Array.isArray(a)) {
                //recursively filter the sub-array
                const output = filter(a, test);

                //store the result
                result.push(output);
            } else {
                //if not an array
                //test the element
                //if it passes the test, store its result
                if (test(a)) {
                result.push(a);
                }
            }
        }

        //return the result
        return result;
    };

    //filter and return
    return filter(originalArray, test);
};
Input:
const arr = [[1, [2, [3, "foo", { a: 1, b: 2 }]], "bar"]];
const filtered = arr.multiFilter((e) => typeof e === "number");
console.log(JSON.stringify(filtered));

Output:
[[1,[2,[3]]]]