javascript 转换 github api 打卡数据
javascript transform github api punchcard data
我需要根据 Github API 调用提供的数据用 D3.js 创建一个条形图:
GET /repos/:username/:repository/stats/punch_card
响应是一个具有以下结构的数组:
Each array contains the day number, hour number, and number of
commits:
0-6: Sunday - Saturday 0-23: Hour of day Number of commits
For example, [2, 14, 25] indicates that there were 25 total commits,
during the 2:00pm hour on Tuesdays. All times are based on the time
zone of individual commits.
Status: 200 OK
[
[
0,
0,
5
],
[
0,
1,
43
],
(...)
[
6,
22,
21
],
[
6,
23,
11
]
]
我需要的是转换此数据和 return 另一个数组,该数组将按天和小时对所有这些信息进行分组。我知道我需要使用 .map(), .filter() ... 但我以前没有函数式编程的经验,我在这里很迷茫。感谢任何帮助。
鉴于上面的示例,我需要 return 2 个不同的数组(绘制两个不同的条形图),如下所示:
commitsByDay = [48, ..., 33] (sum of commits by first element)
commitsByHour = [5, 43, ..., 21, 11] (sum of commits by second element)
谢谢
一种方法是使用reduce
(参考here)。
reduce
函数将对数组中的每个元素应用 reducer 函数。这个函数有两个参数: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
本质上,reducer 是为数组中的每个元素调用的。每次,currentValue
等于当前数组元素,accumulator
等于上一次调用的return值。 reduce
函数的输出是减速器的最后一个 return 值。
对于您的问题,累加器需要跟踪每个周期(天或小时)的总和,而不是总和。为此,累加器应该从一个空数组开始,然后在每次调用 reducer 时进行更新。假设数据在名为 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
使代码更具可读性,但它们不是 必需的 。
我需要根据 Github API 调用提供的数据用 D3.js 创建一个条形图:
GET /repos/:username/:repository/stats/punch_card
响应是一个具有以下结构的数组:
Each array contains the day number, hour number, and number of commits:
0-6: Sunday - Saturday 0-23: Hour of day Number of commits
For example, [2, 14, 25] indicates that there were 25 total commits, during the 2:00pm hour on Tuesdays. All times are based on the time zone of individual commits.
Status: 200 OK
[
[
0,
0,
5
],
[
0,
1,
43
],
(...)
[
6,
22,
21
],
[
6,
23,
11
]
]
我需要的是转换此数据和 return 另一个数组,该数组将按天和小时对所有这些信息进行分组。我知道我需要使用 .map(), .filter() ... 但我以前没有函数式编程的经验,我在这里很迷茫。感谢任何帮助。
鉴于上面的示例,我需要 return 2 个不同的数组(绘制两个不同的条形图),如下所示:
commitsByDay = [48, ..., 33] (sum of commits by first element)
commitsByHour = [5, 43, ..., 21, 11] (sum of commits by second element)
谢谢
一种方法是使用reduce
(参考here)。
reduce
函数将对数组中的每个元素应用 reducer 函数。这个函数有两个参数: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
本质上,reducer 是为数组中的每个元素调用的。每次,currentValue
等于当前数组元素,accumulator
等于上一次调用的return值。 reduce
函数的输出是减速器的最后一个 return 值。
对于您的问题,累加器需要跟踪每个周期(天或小时)的总和,而不是总和。为此,累加器应该从一个空数组开始,然后在每次调用 reducer 时进行更新。假设数据在名为 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
使代码更具可读性,但它们不是 必需的 。