如何在javascript中找到嵌套数组的最大/最小值?

时间:2022-09-28 16:20:37

I want to find the maximum of a nested array, something like this:

我想找到一个嵌套数组的最大值,像这样:

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

but my array contains a text field that I want to discard:

但是我的数组包含一个文本字段,我想要丢弃:

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

5 个解决方案

#1


70  

If you have a nested array of numbers (arrays = [[1, 2], [20, 3]]), nest d3.max:

如果你有一个嵌套的数字数组(数组=[1,2],[20,3]),那么你就可以选择3。

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

Or equivalently, use array.map:

或者说,用array.map:

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

If you want to ignore string values, you can use array.filter to ignore strings:

如果要忽略字符串值,可以使用数组。忽略字符串过滤:

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

Alternatively, if you know the string is always in the first position, you could use array.slice which is a bit more efficient:

或者,如果您知道字符串始终处于第一个位置,则可以使用数组。切片的效率更高一些:

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

Yet another option is to use an accessor function which returns NaN for values that are not numbers. This will cause d3.max to ignore those values. Conveniently, JavaScript's built-in Number function does exactly this, so you can say:

另一种选择是使用accessor函数来返回NaN的值,而这些值不是数字。这将导致d3。max忽略这些值。很方便,JavaScript内置的数字函数做到了这一点,所以你可以说:

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

#2


4  

Use this:

用这个:

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);
}

or better:

或更好:

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;
}

See MDN for Array.filter method details.

看到MDN数组。过滤方法的细节。

#3


2  

If you now exactly what columns you want to test, you can use:

如果您现在想要测试哪些列,可以使用:

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;
}

#4


2  

You can flatten an array and apply a function to each member

您可以将一个数组压平,并对每个成员应用一个函数。

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));

#5


0  

It's a cruel hack, but looking at the source code for d3.max, your best bet might be to define a d3.max1 that discards the first element by copying that code, but replacing i=-1 with i=0. The code at that link is excerpted here. Note that I'm not a regular d3.js user, but from what I know of the library, you're going to want make sure your version has an f.call case like this function does, so that it can respond to live updates correctly.

这是一个残酷的黑客行为,但是看看d3的源代码。max,你最好的选择是定义d3。max1通过复制该代码来丢弃第一个元素,但是将i=-1替换为i=0。该链接的代码在这里摘录。注意,我不是普通的d3。js用户,但是根据我对库的了解,你需要确保你的版本有一个f。像这个函数这样的调用案例可以正确地响应实时更新。

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;
};

Then it would just be d3.max(d3.max1(a)).

那么它就是d3.max(d3.max1(a))。

#1


70  

If you have a nested array of numbers (arrays = [[1, 2], [20, 3]]), nest d3.max:

如果你有一个嵌套的数字数组(数组=[1,2],[20,3]),那么你就可以选择3。

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

Or equivalently, use array.map:

或者说,用array.map:

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

If you want to ignore string values, you can use array.filter to ignore strings:

如果要忽略字符串值,可以使用数组。忽略字符串过滤:

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

Alternatively, if you know the string is always in the first position, you could use array.slice which is a bit more efficient:

或者,如果您知道字符串始终处于第一个位置,则可以使用数组。切片的效率更高一些:

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

Yet another option is to use an accessor function which returns NaN for values that are not numbers. This will cause d3.max to ignore those values. Conveniently, JavaScript's built-in Number function does exactly this, so you can say:

另一种选择是使用accessor函数来返回NaN的值,而这些值不是数字。这将导致d3。max忽略这些值。很方便,JavaScript内置的数字函数做到了这一点,所以你可以说:

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

#2


4  

Use this:

用这个:

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);
}

or better:

或更好:

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;
}

See MDN for Array.filter method details.

看到MDN数组。过滤方法的细节。

#3


2  

If you now exactly what columns you want to test, you can use:

如果您现在想要测试哪些列,可以使用:

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;
}

#4


2  

You can flatten an array and apply a function to each member

您可以将一个数组压平,并对每个成员应用一个函数。

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));

#5


0  

It's a cruel hack, but looking at the source code for d3.max, your best bet might be to define a d3.max1 that discards the first element by copying that code, but replacing i=-1 with i=0. The code at that link is excerpted here. Note that I'm not a regular d3.js user, but from what I know of the library, you're going to want make sure your version has an f.call case like this function does, so that it can respond to live updates correctly.

这是一个残酷的黑客行为,但是看看d3的源代码。max,你最好的选择是定义d3。max1通过复制该代码来丢弃第一个元素,但是将i=-1替换为i=0。该链接的代码在这里摘录。注意,我不是普通的d3。js用户,但是根据我对库的了解,你需要确保你的版本有一个f。像这个函数这样的调用案例可以正确地响应实时更新。

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;
};

Then it would just be d3.max(d3.max1(a)).

那么它就是d3.max(d3.max1(a))。