Как найти максимальный / мин вложенного массива в JavaScript?

javascript d3.js

33125 просмотра

6 ответа

4999 Репутация автора

Я хочу найти максимум вложенного массива, что-то вроде этого:

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

но мой массив содержит текстовое поле, которое я хочу удалить:

a = [["yz",1,2],["xy",20,3]]
d3.max(a) // 20
Автор: nachocab Источник Размещён: 12.05.2012 02:06

Ответы (6)


0 плюса

1506 Репутация автора

Это жестокий хак, но , глядя на исходный код для 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)).

Автор: btown Размещён: 12.05.2012 02:19

4 плюса

2781 Репутация автора

Использовать этот:

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.

Автор: kbec Размещён: 12.05.2012 02:25

2 плюса

81382 Репутация автора

Вы можете сгладить массив и применить функцию к каждому члену

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));
Автор: kennebec Размещён: 12.05.2012 03:19

74 плюса

47106 Репутация автора

Решение

Если у вас есть вложенный массив цифр ( 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));
});

Еще один вариант - использовать функцию доступа, которая возвращает NaNзначения, которые не являются числами. Это заставит d3.max игнорировать эти значения. Удобно, что встроенная Numberфункция JavaScript делает именно это, так что вы можете сказать:

var max = d3.max(arrays, function(array) {
  return d3.max(array, Number);
});
Автор: mbostock Размещён: 12.05.2012 08:15

2 плюса

128 Репутация автора

Если вы теперь точно, какие столбцы вы хотите проверить, вы можете использовать:

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;
}
Автор: Rick Размещён: 08.05.2013 12:00

0 плюса

9651 Репутация автора

d3.arrayобеспечивает, d3.mergeкоторый выравнивает массив массивов.

В сочетании с d3.maxJavascript 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>

Автор: Xavier Guihot Размещён: 16.06.2019 03:35
Вопросы из категории :
32x32