javascript transform данные перфокарты github api - PullRequest
0 голосов
/ 25 ноября 2018

Мне нужно создать гистограмму с D3.js на основе данных, предоставленных вызовом API Github:

GET /repos/:username/:repository/stats/punch_card

Ответ - это массив со следующей структурой:

Каждый массив содержит номер дня, номер часа и количество коммитов:

0-6: воскресенье - суббота 0-23: час дня Количество коммитов

Например,[2, 14, 25] указывает на то, что всего было зафиксировано 25 коммитов в течение часа в 14:00 по вторникам.Все времена основаны на часовом поясе отдельных коммитов.

Status: 200 OK
[
  [
    0,
    0,
    5
  ],
  [
    0,
    1,
    43
  ],
  (...)
  [
    6,
    22,
    21
  ], 
  [
    6,
    23,
    11
  ]
]

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

Учитывая приведенный выше пример, мне нужно вернуть 2 разных массива (для рисования двух разных гистограмм), например:

commitsByDay = [48, ..., 33] (sum of commits by first element)

commitsByHour = [5, 43, ..., 21, 11] (sum of commits by second element)

Спасибо

1 Ответ

0 голосов
/ 26 ноября 2018

Один из подходов заключается в использовании reduce (ссылка здесь ).

Функция reduce будет применять функцию редуктор к каждому элементу в массиве.,Эта функция имеет два аргумента: accumulator и currentValue.

Самое основное сокращение получает сумму списка.Вот пример:

let numbers = [1,2,3,4,5];
let sum = numbers.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
});
sum; //has a value of (1 + 2) + 3) + 4) + 5 = 15

По сути, редуктор вызывается для каждого элемента в массиве.Каждый раз currentValue равен текущему элементу массива, а accumulator равен возвращаемому значению предыдущего вызова .Выходом функции reduce является последнее возвращаемое значение редуктора.

В вашей задаче аккумулятор должен отслеживать сумму за период (день или час), а не общую сумму.Для этого аккумулятор должен начинаться как пустой массив, а затем обновляться при каждом вызове редуктора.Предполагая, что данные находятся в переменной с именем response, вы можете получить данные за день:

let commitsByDay = response.reduce(
  (accumulator, currentValue) => {
    // "currentValue" is an individual record, stored as [day, hour, commits]
    let day = currentValue[0]; 
    let commits = currentValue[2];

    // "accumulator" contains the number of commits per day in an array
    // The index of the array corresponds to the day number
    // We will update the accumulator to contain the data from "currentValue"
    accumulator[day] = (accumulator[day] || 0) + commits;

    // The "accumulator" must be returned
    return accumulator;
  }, 
  [] // The initial value for "accumulator" is an empty array
);
commitsByDay; // Now contains the final value of "accumulator"

Примечание

Хотя reduce это хорошо, вы не нужно чтобы его использовать.Вы можете сделать то же самое, используя цикл for.Как правило, reduce, map и filter делают код более читабельным, но они не необходимы .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...