Comment trouver le max / min d'un tableau imbriqué dans javascript?

Je veux trouver le maximum d'un tableau imbriqué, quelque chose comme ceci:

a = [[1,2],[20,3]] d3.max(d3.max(a)) // 20 

Mais mon tableau contient un champ de texte que je souhaite jeter:

 a = [["yz",1,2],["xy",20,3]] d3.max(a) // 20 

Si vous avez un ensemble de nombres imbriqués ( arrays = [[1, 2], [20, 3]] ), nid d3.max :

 var max = d3.max(arrays, function(array) { return d3.max(array); }); 

Ou, de manière équivalente, utilisez array.map :

 var max = d3.max(arrays.map(function(array) { return d3.max(array); })); 

Si vous souhaitez ignorer les valeurs des chaînes, vous pouvez utiliser array.filter pour ignorer les chaînes:

 var max = d3.max(arrays, function(array) { return d3.max(array.filter(function(value) { return typeof value === "number"; })); }); 

Sinon, si vous savez que la chaîne est toujours dans la première position, vous pouvez utiliser array.slice qui est un peu plus efficace:

 var max = d3.max(arrays, function(array) { return d3.max(array.slice(1)); }); 

Encore une autre option est d'utiliser une fonction d'accesseur qui renvoie NaN pour des valeurs qui ne sont pas des nombres. Cela entraînera que d3.max ignore ces valeurs. De manière pratique, la fonction de Number intégrés de JavaScript fait exactement cela, donc vous pouvez dire:

 var max = d3.max(arrays, function(array) { return d3.max(array, Number); }); 

Utilisez ceci:

 function arrmax(arrs) { var toplevel = []; var f = function(v) { return !isNaN(v); }; for (var i = 0, l = arrs.length; i<l; i++) { toplevel.push(Math.max.apply(window, arrs[i].filter(f))); } return Math.max.apply(window, toplevel); } 

ou mieux:

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

Voir les détails de la méthode MDN for Array.filter.

Si vous avez exactement exactement quelles colonnes vous souhaitez tester, vous pouvez utiliser:

 var columns = ["ColumnA", "ColumnB", "ColumnC"]; var max = selectedMax(columns,dataset); var min = selectedMin(columns,dataset) function selectedMax(columns, dataset) { var max; columns.forEach(function(element, index, array) { var tmpmax = d3.max(dataset, function(d) { return +d[element]; }); max = (tmpmax > max || max === undefined) ? tmpmax : max; }); return max; } function selectedMin(columns, dataset) { var min; columns.forEach(function(element, index, array) { var tmpmin = d3.min(dataset, function(d) { return +d[element]; }); min = (tmpmin < min || min === undefined) ? tmpmin : min; }); return min; } 

Vous pouvez aplatir un tableau et appliquer une fonction à chaque membre

 Array.prototype.flatten= function(fun){ if(typeof fun!= 'function') fun= ''; var A= [], L= this.length, itm; for(var i= 0; i<L; i++){ itm= this[i]; if(itm!= undefined){ if(!itm.flatten){ if(fun) itm= fun(itm); if(itm) A.push(itm); } else A= A.concat(itm.flatten(fun)); } } return A; } var a= [["yz", 1, 2], ["xy", 20, 3]], max=-Infinity; var max=Math.max.apply(a, a.flatten(Number)); 

C'est un hack cruel, mais en regardant le code source pour d3.max , votre meilleur pari pourrait être de définir un d3.max1 qui rejette le premier élément en copiant ce code, mais en remplaçant i=-1 par i=0 . Le code sur ce lien est ici extrait. Notez que je ne suis pas un utilisateur régulier de d3.js, mais à partir de ce que je connais de la bibliothèque, vous allez vouloir vous assurer que votre version dispose d'un cas f.call comme celui-ci, de sorte qu'il puisse répondre à la vie Mises à jour correctement.

 d3.max = function(array, f) { var i = -1, n = array.length, a, b; if (arguments.length === 1) { while (++i < n && ((a = array[i]) == null || a != a)) a = undefined; while (++i < n) if ((b = array[i]) != null && b > a) a = b; } else { while (++i < n && ((a = f.call(array, array[i], i)) == null || a != a)) a = undefined; while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; } return a; }; 

Alors ce serait juste d3.max(d3.max1(a)) .