我被要求在一个随机推文的大文本文件中计算每天每小时推文的数量(0 - 23)。日期不是很有趣,只有每小时的推文。我想在一个新的对象数组中返回它们。每个对象应该具有属性小时和计数如下:
{hour: x, count: y},
我已经创建了一个函数,我在声明一个空数组,我将在其中放入我的数据:
function(tweets) {
let result = [];
我想我需要像这样推他们:
result.push({hour: x, count: y});
但我不知道如何从我的对象(键和值)中提取特定小时。
在巨大的原始数据文件中,每条推文都会记录下这样的日期:
created_at: "30-06-2015 14:27",
有什么建议或经验吗?我目前正在学习正则表达式和for循环。我应该在这段代码中使用它们还是有更聪明的方法?
编辑:当您询问更多详细信息时:原始数据是具有以下结构的数组中的对象:
{
time: Date-object,
created_at: "30-06-2015 14:27",
fromUsername: "victor",
text: "asyl og integration",
lang: "da",
source: "Twitter for Android",
}
关于提取文本我看到很好的答案here。而不是console.log
添加解析并保存到您的阵列。
关于regexp - 我认为应该是这样的
var re = /created_at: \"([^\"]*)\",/g;
我要做的是从不同的角度开展工作:创建一个带有dateTimeHour的对象,用于您关心的每小时的开始。它可能应该是有限的时间跨度,就像之前发生的所有推文一样:
因此,生成一些动态的东西:
{
'2019-03-01T17:22:30Z': 0, // or simply '1552667443928'
'2019-03-01T18:22:30Z': 0,
'2019-03-01T19:22:30Z': 0,
'2019-03-01T20:22:30Z': 0,
...etc
}
您可以使用当前日期然后循环创建其他以前的日期时间:
const now = new Date()
// you can use a generator here or simply a while loop:
const dateTimes = {}
while(now > REQUIRED_DATE)
dateTimes[new Date(now.setHours(now.getHours() - 1))] = 0
现在你有一份精疲力竭的所有时间清单。
然后,检查给定的推文是否在那个小时内:检查是否item.created_at < currentHourBeingLooked
,因为你应该循环通过Object.keys(dateTimes)
。
然后,循环遍历列表中的每个项目,并检查它是否适合该dateTime,如果这样增加dateTimes[currentHour]++
。
因此,最难的部分是将created_at转换为正常的日期时间字符串:
const [datePortion, timePortion] = "30-06-2015 14:27".split(' ')
const [day, month, year] = datePortion.split('-')
const [hour, minute] = timePortion.split(':')
现在有了所有日期,月份,年份,小时和分钟,你可以在javascript中构建一个时间对象:它遵循以下公式:来自MDN:
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
又名:
new Date(year, monthIndex, day, hours, minutes, seconds);
因此,对于2019年12月17日凌晨3:24,这将是:
const = new Date(2019, 11, 17, 3, 24, 0);
我假设你已经知道从Ralkov指向的帖子中使用正则表达式来获取你所有的created_at
日期,我的回答将从那里开始。
你说日期并不重要所以一旦你有了字符串
'created_at: "30-06-2015 14:27"'
除了小时之外我们需要摆脱一切,我通过提取子串来做到这一点,随意尝试其他方法,这只是为了让你开始。
var date = obj.substr(obj.indexOf(' ') + 1);
var time = date.substr(date.indexOf(' ') + 1);
var hour = time.substr(0, time.indexOf(':'));
会得到你的时间
"14"
请注意,这仅适用于一天,如果您希望在同一数据结构中存储不同日期的推文小时数,则需要进行一些其他更改
当您编写for循环时,每次找到推文并且已经提取了hour
时,使用以下函数,它将值对的组合存储到函数外部定义的映射变量中,必要时创建新对或仅更新它随着新的推特计数。
function newTweet(hour, tweetsPerHour) {
var tweetsThisHour = tweetsPerHour.get(hour);
tweetsThisHour = tweetsThisHour === undefined ? 0 : tweetsThisHour;
tweetsPerHour.set(hour, ++tweetsThisHour);
console.log(tweetsThisHour)
}
完整代码:
var obj = 'created_at: "30-06-2015 14:27"';
var date = obj.substr(obj.indexOf(' ')+1);
var time = date.substr(date.indexOf(' ')+1);
var hour = time.substr(0, time.indexOf(':'));
var tweetsPerHour = new Map();
newTweet(hour, tweetsPerHour); //this is the extracted hour
newTweet("16", tweetsPerHour); //you can try different hours as well
newTweet("17", tweetsPerHour);
function newTweet(hour, tweetsPerHour) {
var tweetsThisHour = tweetsPerHour.get(hour);
tweetsThisHour = tweetsThisHour === undefined ? 0 : tweetsThisHour;
tweetsPerHour.set(hour, ++tweetsThisHour);
console.log(hour + " tweet count: " + tweetsThisHour)
}
代码正在做的是成对存储推文的小时数和计数:
[{"14":1} ,{"16":1}, {17:1}]
例如,如果再次添加“14”,它将更新为
[{"14":2}, {"16":1}, {17:1}]
深入研究JavaScript Map Objects。
您的代码流如下所示: