[英]Javascript: Filtering a key in Json object with the elements of one array?
a couple of classic disclaimers first (and a Hello everyone, because I don't know why it keeps cutting these 2 words if I put them at the beginning:):首先是几个经典的免责声明(还有大家好,因为我不知道为什么如果我把它们放在开头,它会一直删掉这两个词:):
My problem: basically, from a Json which contains a lot of records in the format {"date": "MM-DD-YYYY", "temperature": integer} I am trying to build a sort of interactive script that will take all the different months in that json, and will automatically give me the average temperature for that month.我的问题:基本上,从 Json 中包含大量格式为 {"date": "MM-DD-YYYY", "temperature": integer} 的记录json 中的不同月份,并会自动给我该月的平均温度。 So if you change the array and add 1 month of records, immediately I get also the new average for the new month.
因此,如果您更改数组并添加 1 个月的记录,我会立即得到新月份的新平均值。
So, starting from the Json, my steps are to make an array with all the months included in the file (not every month is included) with a map and new date... then I will transform the "javascript months" (which starts from 0... but in the Json january is not 0 but 1) to make an array of months included in "string form" where Jan = "01", Feb = "02" and so on.因此,从 Json 开始,我的步骤是创建一个数组,其中包含文件中包含的所有月份(不是每个月都包含在内)以及 map 和新日期......然后我将转换“javascript 月份”(开始从 0... 但在 Json 中,一月不是 0,而是 1) 以制作包含在“字符串形式”中的月份数组,其中 Jan =“01”,Feb =“02”等。
After that I am lost: I have tried a lot of combination with loops, nested loops, forEach, but I can't figure out a way to say to Javascript: "for every item in this array of months, take all the relative records from the Json, and give me an Avg Temperature!"在那之后我迷路了:我尝试了很多与循环、嵌套循环、forEach 的组合,但我想不出一种方法来对 Javascript 说:“对于这个月份数组中的每个项目,获取所有相关记录从 Json 给我一个平均温度!”
Basically what I would like to achieve is simple: from a given Json in that format, I retrieve an array of the months, and the end results = an array of average temperatures, 1 avg temp for every month.基本上我想要实现的目标很简单:从给定的 Json 格式中,我检索月份数组,最终结果 = 平均温度数组,每个月 1 个平均温度。
I'll try to post what I did until now (only the functioning parts)!我将尝试发布我到目前为止所做的(仅功能部分)!
Thank you in advance!先感谢您!
const dates = [
{"date": "01-24-2020", "temps": 1},
{"date": "01-31-2020", "temps": -1},
{"date": "02-01-2020", "temps": 6},
{"date": "02-02-2020", "temps": 2},
{"date": "03-03-2020", "temps": 1},
{"date": "03-04-2020", "temps": 1},
{"date": "04-06-2020", "temps": -2},
{"date": "04-08-2020", "temps": -4}]
const singleMonths = Array.from(new Set(dates.map(elem => new Date(elem.date).getMonth())))
const singleMonthString = singleMonths.map(m => `${"0"+(m+1)}`)
//after this I tried A LOT of different solutions, but I can only filter manually for a singular item in my Array, and not how I would like to, automatically for all my items in my array!
const damnFilter = dates.filter(m => m.dates.substring(0,2)==result[0])
I don't know if it is that you want, but here I created some of the snippet, where it gets four months and averages each month temperature:我不知道它是否是你想要的,但在这里我创建了一些片段,它有四个月的时间和每个月的平均温度:
let newDates = [];
for(let i = 1; i <= 12; i++){
newDates = dates.filter(date => new Date(date.date).getMonth() + 1 == i)
if(newDates.length > 0){
let accumulator = 0;
newDates.map(day => accumulator += day.temps);
console.log("Average: ", accumulator / newDates.length);
}
}
Some comments on your code:对您的代码的一些评论:
const singleMonths = Array.from(new Set(dates.map(elem => new Date(elem.date).getMonth())))
is quite inefficient.效率很低。 The data is already an array, there's no need to create a new array through map , convert it to a set, then back to another array.
数据已经是一个数组,不需要通过map创建一个新数组,将其转换为一个集合,然后再返回另一个数组。 Also, there's no need to create a Date to get the month, not to mention the inefficiency of doing the +1 via another map when it could be done in the above line (if it was needed).
此外,无需创建 Date 来获取月份,更不用说通过另一个 map 执行 +1 的低效率了,而它可以在上面的行中完成(如果需要的话)。
The format dd-mm-yyyy is not supported by ECMAScript so parsing is implementation dependent. ECMAScript 不支持 dd-mm-yyyy 格式,因此解析依赖于实现。 Safari at least treats it as an invalid date, see Why does Date.parse give incorrect results?
Safari 至少将其视为无效日期,请参阅Why does Date.parse give incorrect results?
const singleMonthString = singleMonths.map(m => `${"0"+(m+1)}`)
If the +1 was needed, better to do it in the first map, and even if you need to do it, why create another array?如果需要 +1,最好在第一个 map 中完成,即使需要,为什么还要创建另一个数组? Just use forEach and modify the existing array.
只需使用forEach并修改现有数组。
const damnFilter = dates.filter(m => m.dates.substring(0,2)==result[0])
result isn't declared or initialised anywhere so that's not going anywhere. result没有在任何地方声明或初始化,所以它不会去任何地方。
You can use reduce on the data array to sum the temperatures for a particular month and generate an average.您可以对数据数组使用reduce来对特定月份的温度求和并生成平均值。 It's convenient to keep the values for sum and count for a month in the accumulator that is passed to each subsequent loop.
在传递给每个后续循环的累加器中将 sum 和 count 的值保留一个月很方便。 You can then generate a new average each time or do it at the end.
然后您可以每次生成一个新的平均值或在最后生成一个平均值。 Calculating the average each time is simpler but possibly less efficient if the data file is large.
如果数据文件很大,每次计算平均值会更简单,但效率可能会降低。 But for a small file the difference will be negligible.
但是对于小文件来说,差异可以忽略不计。
let data = [ {"date": "01-24-2020", "temps": 1}, {"date": "01-31-2020", "temps": -1}, {"date": "02-01-2020", "temps": 6}, {"date": "02-02-2020", "temps": 2}, {"date": "03-03-2020", "temps": 1}, {"date": "03-04-2020", "temps": 1}, {"date": "04-06-2020", "temps": -2}, {"date": "04-08-2020", "temps": -4} ]; let averageData = data.reduce((acc, obj) => { // Get month number let month = obj.date.slice(0,2); // If accumulator doesn't have a summary object for // that month, add it with initial values if (:acc[month]) { acc[month] = {sum,0: count,0: year. obj.date;slice(-4)}. } // Update summary values for the month acc[month].sum += obj;temps. acc[month];count += 1. acc[month].average = acc[month].sum / acc[month];count; // Return the accumulator return acc, // Use a completely emtpy object for the accumulator }. Object;create(null)). // Show averageData object console;log(averageData): // Show data as month. average Object.keys(averageData).forEach(key => console.log( new Date(averageData[key],year. key-1),toLocaleString('en':{month,'short': year:'numeric'}) + '. ' + averageData[key];average ));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.