Find the Max and Min element out of all the nested arrays in javascript
Asked Answered
K

9

8

I have a array like so:

var arr = [[12,45,75], [54,45,2],[23,54,75,2]];

I want to find out the largest element and the smallest element out of all the elements in the nested array:

The min should be: 2

and

Max should be 75

I tried the functions below but they do not work:

    function Max(arrs)
    {
        if (!arrs || !arrs.length) return undefined;
        let max = Math.max.apply(window, arrs[0]), m,
            f = function(v){ return !isNaN(v); };
        for (let i = 1, l = arrs.length; i<l; i++) {
            if ((m = Math.max.apply(window, arrs[i].filter(f)))>max) max=m;
        }
        return max;
    }
    function Min(arrs)
    {
        if (!arrs || !arrs.length) return undefined;
        let min = Math.min.apply(window, arrs[0]), m,
            f = function(v){ return !isNaN(v); };
        for (let i = 1, l = arrs.length; i<l; i++) {
            if ((m = Math.min.apply(window, arrs[i].filter(f)))>min) min=m;
        }
        return min;
    }

It gives out Max as 75 and min as 12.

Any guidance will be appreciated.

Also tried other answers in SO but none help.

The answer at Merge/flatten an array of arrays in JavaScript? resolves the problem of merging arrays.

Whereas my problem is to keep the array as is and perform operations.

Kaiserism answered 7/12, 2017 at 9:30 Comment(2)
why the check for number? do you expect NaN values?Burson
Possible duplicate of Merge/flatten an array of arrays in JavaScript?Daisie
F
27

Assuming ES6

const arr = [[12,45,75], [54,45,2],[23,54,75,2]];

const max = Math.max(...[].concat(...arr));

const min = Math.min(...[].concat(...arr));

console.log(max);

console.log(min);
Fem answered 7/12, 2017 at 9:33 Comment(1)
This answer is the most precise one I am looking for, thank you for the efforts.Kaiserism
H
6

You can flatten the array first (advantage - will work for nested arrays at multiple levels)

var flattenedArr = [[12,45,75], [54,45,2],[23,54,75,2] ].toString().split(",").map(Number);

Then get the min and max from the flattened array

var max = Math.max.apply( null, flattenedArr );
var min = Math.min.apply( null, flattenedArr );

Demo

var flattenedArr = [
  [12, 45, 75],
  [54, 45, 2],
  [23, 54, 75, 2]
].toString().split(",").map(Number);

var max = Math.max.apply(null, flattenedArr);
var min = Math.min.apply(null, flattenedArr);

console.log(max, min);
Hagen answered 7/12, 2017 at 9:33 Comment(0)
B
2

UPDATE 2024

Get a flat array and take min or max value by spreading the values.

const
    values = [[12, 45, 75], [54, 45, 2], [23, 54, 75, 2]],
    flat = values.flat(),
    min = Math.min(...flat),
    max = Math.max(...flat);

console.log(min);
console.log(max);
A ES5 recursive approach by checking the type. It works for deep nested arrays.

var array = [[12, 45, 75], [54, 45, 2], [23, 54, 75, 2]],
    min = array.reduce(function min(a, b) {
        return Math.min(Array.isArray(a) ? a.reduce(min) : a, Array.isArray(b) ? b.reduce(min) : b);
    }),
    max = array.reduce(function max(a, b) {
        return Math.max(Array.isArray(a) ? a.reduce(max) : a, Array.isArray(b) ? b.reduce(max) : b);
    });
    
console.log(min, max);

With functions for using as callback.

function flat(f, v) { return Array.isArray(v) ? v.reduce(f) : v; }
function getMin(a, b) { return Math.min(flat(getMin, a), flat(getMin, b)); }
function getMax(a, b) { return Math.max(flat(getMax, a), flat(getMax, b)); }

var array = [[12, 45, 75], [54, 45, 2], [23, 54, 75, 2]],
    min = array.reduce(getMin),
    max = array.reduce(getMax);
    
console.log(min, max);
Burson answered 7/12, 2017 at 9:42 Comment(2)
Note: this doesn't work if only one array is passed (e.g. [[3,2,1]].reduce(getMin)) or if empty arrays are passed (e.g. [[3,2,1],[]].reduce(getMin)).Endometrium
@Robert, right. actually i would use another approach. please see edit.Burson
E
1

You can simply merged all the nested array into a single array and then find minimum and maximum value by using Math.min.apply(null, array) and Math.max.apply(null, array)

var arr = [[12,45,75], [54,45,2],[23,54,75,2]];
var merged = [].concat.apply([], arr);
var max = Math.max.apply(null, merged);
var min = Math.min.apply(null, merged);
console.log(max,min)
Expressly answered 7/12, 2017 at 9:38 Comment(0)
C
0

Solution without concatenation, which works for any level of nesting

let arr = [[12,45,75], [54,45,2],[23,54,75,2]];

function findMaxFromNestedArray(arr) {
  let max = Number.MIN_SAFE_INTEGER;
  
  for (let item of arr) {
    if(Array.isArray(item)) {
      let maxInChildArray = findMaxFromNestedArray(item);
      if (maxInChildArray > max) {
        max = maxInChildArray;
      }
    } else {
      if (item > max) {
        max = item;
      }
    }
  }
  
  return max;
}

console.log(findMaxFromNestedArray(arr))
Chaplet answered 7/12, 2017 at 9:48 Comment(0)
R
0

Solution with only one reduce:

const getMaxMin = (flattened) => {
return flattened.reduce(
        (a, b) => {            
            return {
                maxVal: Math.max(b, a.maxVal),
                minVal: Math.min(b, a.minVal),                
            };
        },
        {
            maxVal: -Infinity,
            minVal: Infinity,            
        }
    );
}
const flatSingle = arr => [].concat(...arr)
const maxMin = getMaxMin(flatSingle(arr))
console.log(maxMin);
Regelation answered 5/9, 2019 at 9:58 Comment(0)
N
0

We can flatten the array with Array.prototype.flat. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat

const nestedArray = [[12,45,75], [54,45,2],[23,54,75,2]]
const flattenedArray = nestedArray.flat(2)

const minValue = Math.min.apply(null, flattenedArray)
const maxValue = Math.max.apply(null, flattenedArray)

console.log( {flattenedArray, minValue, maxValue} )
Nerveracking answered 6/1, 2020 at 9:48 Comment(0)
S
0

const getFlatArr = (arr) => arr.join().split(',').map(Number)

const getMax = (arr) => {
  const newArr = getFlatArr(arr)
  let max = newArr[0]
  newArr.forEach((value) => {
    max = value > max ? value : max
  })
  return max
}

const getMin = (arr) => {
  const newArr = getFlatArr(arr)
  let min = newArr[0]
  newArr.forEach((value) => {
    min = value < min ? value : min
  })
  return min
}

const arr1 = [
  [12, 45, 75],
  [54, 45, 2],
  [23, 54, 75, 2],
]
console.log(`Max: ${getMax(arr1)}`)
console.log(`Min: ${getMin(arr1)}`)

const arr2 = [1, 2, [14, 56, 34, [48, 98]], [14, 16, 11, [18, 81]], 34, 35]
console.log(`Max: ${getMax(arr2)}`)
console.log(`Min: ${getMin(arr2)}`)
Schweinfurt answered 2/12, 2021 at 20:13 Comment(0)
B
0

I'm just gonna update this with 3 simple approaches:

Assume you have a nested array:

let numbers = [12, 44, [33, 94, 10444], 104]

Your first step is to flatten the array. There are many ways to do this, but specifically 2 of the most simple ways:

const flat = numbers.flat() // 12, 44, 33, 94, 10444, 104 
const flat = [].concat(...numbers) // 12, 44, 33, 94, 10444, 104 

Then comes the easy part - determining the min/max of the flattened array:

const min = Math.min(...flat) // 12
const max = Math.max(...flat) // 10444

Alternatively, you can sort the flattened array and get the first and last elements:

flat.sort((a,b) => {return a-b}) // 12, 33, 44, 94, 104, 10444
const min = flat.shift() // 12
const max = flat.pop() // 104444
Bingham answered 17/4, 2022 at 12:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.