2016-06-07 2 views
1

У меня есть массив таких массивов.Вложение d3.max с массивом массивов

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():

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

Я изо всех сил, чтобы понять, как на самом деле работает этот код. Я знаю, что второй аргумент функции d3.max() указывает функцию доступа, но я смущен тем, как точно вызов d3.max() дважды связан с функцией accessor.

Я предполагаю, что я прошу об этом, так как javascript интерпретирует этот код. Я прошел через консоль, но к сожалению, это не помогло.

ответ

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

+0

Это действительно четкое объяснение. Удивительно, как имена переменных могут существенно повлиять на понимание конкретной части кода! – puzzler10

+0

Thx. Наверное, мы только что видели экземпляр «поиска подходящей проблемы имен». – pintxo

0

Вау ..! интригующий вопрос на самом деле. Для некоторых спортивных целей здесь есть решение этой проблемы с помощью ES6 с помощью метода массива под названием Array.prototype.maxByKey() Итак, вы можете видеть, как на самом деле он реализован чистым 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);

Вот история о том, что происходит в этой части кода. Мы найдем индекс объекта путем уменьшения. В нашем методе сокращения используется начальное значение, которое представляет собой массив [0,Number.MIN_VALUE], который при индексе 0 имеет 0 и в позиции индекса 1 имеет наименьшее возможное число в JS. Начальным значениям присваивается первый аргумент. Итак, здесь m начинается с начального значения. Сокращение будет проходить по элементам массива (объекты в нашем случае) один за другим, и каждый раз o будет назначен текущему объекту, а последний аргумент i - это, конечно, индекс позиции, в которой мы сейчас работаем. k предоставляется нашей функции в качестве ключа, который мы будем использовать для проверки максимального значения.

Так что это просто тройная сравнение o[k] > m[1] ? [i,o[k]] : m что означает проверить текущее свойство объекта, данное k (o[k]), если оно меньше, чем m[1] (где m является [0,Number.MIN_VALUE] в первую очередь) возвращает m в [i,o[k]] (проверить, как триады вернуть результат), если он не меньше m[1], тогда возвратите m как есть. И в конце прогулки мы будем уменьшаться до [index of the element with max k property value, the value of that k property] в этом массиве.

Итак, как вы видите, это очень просто.

+0

'var m = this.reduce ((m, o, i) => o [k]> m [1]? [I, o [k]]: m, [0, Number.MIN_VALUE]); линия выглядит непостижимой для меня, не зная, что такое 'm',' o', 'i'. – paradite

+0

@paradite ОК, да, вы правы. Он выглядит загадочным, но на самом деле он очень прост. Я добавил некоторые объяснения в ответ. – Redu

Смежные вопросы