使用数组数组嵌套d3.max

时间:2016-06-07 20:43:21

标签: javascript arrays d3.js

我有一个像这样的数组。

data = [
  [
    {x: 1, y: 40},
    {x: 2, y: 43},
    {x: 3, y: 12},
    {x: 4, y: 60},
    {x: 5, y: 63},
    {x: 6, y: 23}
 ], [
    {x: 1, y: 12},
    {x: 2, y: 5},
    {x: 3, y: 23},
    {x: 4, y: 18},
    {x: 5, y: 73},
    {x: 6, y: 27}
 ], [
    {x: 1, y: 60},
    {x: 2, y: 49},
    {x: 3, y: 16},
    {x: 4, y: 20},
    {x: 5, y: 92},
    {x: 6, y: 20}
  ] 
];

我可以通过嵌套的d3.max()调用找到 data 的最大y值:

d3.max(data, function(d) {
  return d3.max(d, function(d) {
    return d.y;
  });
});

我很难理解这段代码是如何运作的。我知道d3.max()函数的第二个参数指定了一个访问器函数 - 但是我对于调用d3.max()两次与访问器函数的确切关系感到困惑。

我想我要求的是javascript如何解释这段代码的演练。我已经在控制台上浏览了它,但不幸的是它并没有帮助。

2 个答案:

答案 0 :(得分:2)

有时它只是变量的命名:

// the outer function iterates over the outer array
// which we can think of as an array of rows

d3.max(data, function(row) {

  // while the inner function iterates over the inner
  // array, which we can think of as an array containing
  // the columns of a single row. Sometimes also called
  // a (table) cell.

  return d3.max(row, function(column) {
    return column.y;
  });

});

您可以在此处找到d3.max函数的源代码:https://github.com/d3/d3.github.com/blob/8f6ca19c42251ec27031376ba9168f23b9546de4/d3.v3.js#L69

答案 1 :(得分:0)

哇..!真正有趣的问题。仅仅为了一些运动目的,这是通过发明一个名为Array.prototype.maxByKey()的数组方法来解决这个问题的ES6。所以在这里你可以看到它实际上是由纯JS实现的。

Array.prototype.maxByKey = function(k) {
  var m = this.reduce((m,o,i) => o[k] > m[1] ? [i,o[k]] : m ,[0,Number.MIN_VALUE]);
  return this[m[0]];
};
var data = [
[{x: 1, y: 40},{x: 2, y: 43},{x: 3, y: 12},{x: 4, y: 60},{x: 5, y: 63},{x: 6, y: 23}],
[{x: 1, y: 12},{x: 2, y: 5},{x: 3, y: 23},{x: 4, y: 18},{x: 5, y: 73},{x: 6, y: 27}],
[{x: 1, y: 60},{x: 2, y: 49},{x: 3, y: 16},{x: 4, y: 20},{x: 5, y: 92},{x: 6, y: 20}]
],
maxObj = data.map(a => a.maxByKey("y")).maxByKey("y");
console.log(maxObj);

以下是这段代码中发生的事情的故事。我们将通过减少找到对象的索引。我们的reduce方法使用一个初始值,即数组[0,Number.MIN_VALUE],它在索引0处有0,在索引1位置具有JS中可能的最小数字。初始值设置为第一个参数。所以这里m以初始值开头。 Reduce将逐个遍历数组项(在我们的例子中是对象),每次o将被分配给当前对象,最后一个参数i当然是我们所在位置的索引目前正在努力。 k被提供给我们的函数作为我们将用于测试最大值的关键。

所以有这个简单的三元比较o[k] > m[1] ? [i,o[k]] : m,这意味着检查ko[k])给出的当前对象属性是否小于m[1](其中{{1}在第一个回合中是m[0,Number.MIN_VALUE]返回m(检查三元组返回结果的方式),如果它不小于[i,o[k]]则返回m[1]原样。在步行结束时,我们将在该阵列中缩小到m

所以你看,它很简单。