Я хочу найти максимум вложенного массива, примерно так:
a = [[1,2],[20,3]]
d3.max(d3.max(a)) // 20
но мой массив содержит текстовое поле, которое я хочу отменить:
a = [["yz",1,2],["xy",20,3]]
d3.max(a) // 20
Я хочу найти максимум вложенного массива, примерно так:
a = [[1,2],[20,3]]
d3.max(d3.max(a)) // 20
но мой массив содержит текстовое поле, которое я хочу отменить:
a = [["yz",1,2],["xy",20,3]]
d3.max(a) // 20
Если у вас есть вложенный массив чисел (arrays = [[1, 2], [20, 3]]
), гнездо d3.max:
var max = d3.max(arrays, function(array) {
return d3.max(array);
});
Или, что то же самое, используйте array.map:
var max = d3.max(arrays.map(function(array) {
return d3.max(array);
}));
Если вы хотите игнорировать строковые значения, вы можете использовать array.filter для игнорирования строк:
var max = d3.max(arrays, function(array) {
return d3.max(array.filter(function(value) {
return typeof value === "number";
}));
});
В качестве альтернативы, если вы знаете, что строка всегда находится в первой позиции, вы можете использовать array.slice, которая немного эффективнее:
var max = d3.max(arrays, function(array) {
return d3.max(array.slice(1));
});
Еще один вариант - использовать функцию accessor, которая возвращает NaN
для значений, которые не являются номерами. Это приведет к тому, что d3.max игнорирует эти значения. Удобно, встроенная функция Number
JavaScript выполняет именно это, поэтому вы можете сказать:
var max = d3.max(arrays, function(array) {
return d3.max(array, Number);
});
Используйте это:
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);
}
или лучше:
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;
}
См. MDN для подробных сведений о Array.filter.
Вы можете сгладить массив и применить функцию к каждому члену
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));
Если вы точно знаете, какие столбцы вы хотите проверить, вы можете использовать:
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;
}
Это жестокий взлом, но, глядя на исходный код для d3.max
, лучшим вариантом может быть определение d3.max1
, которое отбрасывает первый элемент, копируя этот код, но заменяя i=-1
на i=0
. Код на этой ссылке выписан здесь. Обратите внимание, что я не обычный пользователь d3.js, но из того, что я знаю о библиотеке, вы захотите убедиться, что ваша версия имеет случай f.call
, такой как эта функция, так что он может отвечать на живые правильно обновляется.
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;
};
Тогда это будет просто d3.max(d3.max1(a))
.
d3.array
предоставляет d3.merge
который выравнивает массив массивов.
В сочетании с d3.max
и javascript Number
в качестве средства доступа:
var max = d3.max(d3.merge(arrays), Number);
Например:
var input = [["yz", 1, 2], ["xy", 20, 3]];
var max = d3.max(d3.merge(input), Number);
console.log(max);
<script src="https://d3js.org/d3-array.v2.min.js"></script>