简体   繁体   English

如何按一个元素分组并在 Javascript 中找到另一个元素的平均值?

[英]How do I group by one element and find the average of another in Javascript?

I am working on a project comparing the age of wine to it's score and want to make a line chart with age on the X axis and average score for each age on the Y. I have an array of objects each containing two elements, age and score and want to group by each age and find the average score for that age.我正在做一个项目,将葡萄酒的年龄与其分数进行比较,并希望制作一个折线图,X 轴为年龄,Y 轴为每个年龄的平均分数。我有一个对象数组,每个对象包含两个元素,年龄和score 并希望按每个年龄分组并找到该年龄的平均分数。

I have a CSV file created by doing a request from Global Wine Score that has vintage, review date, score etc. In python, I created a column for age by subtracting the review year from the vintage.我通过执行来自 Global Wine Score 的请求创建了一个 CSV 文件,其中包含年份、审查日期、分数等。在 python 中,我通过从年份中减去审查年份创建了一个年龄列。 In Javascript I created a new array doing this:在 Javascript 中,我创建了一个新数组:

    var newArr = countryFilter.map(function(elem) {
            return {
                age: elem.wine_age,
                score: elem.score
            };
        });

here is what my array looks like:这是我的数组的样子:

0: Object { age: "116", score: "98.51" }

​​​​
age: "116"

​​​​
score: "98.51"

​​​
​​​
1: Object { age: "113", score: "84.46" }

​​​​
age: "113"

​​​​
score: "84.46"

length: 23258

I tried this, but any object with more than 1 unique score yields NAN.我试过了,但是任何具有超过 1 个唯一分数的对象都会产生 NAN。

 const reduced = newArr.reduce(function(m, d){
        if(!m[d.age]){
          m[d.age] = {...d, count: 1};
          return m;
        }
        m[d.age].score += d.score;
        m[d.age].count += 1;
        return m;
     },{});

     const result = Object.keys(reduced).map(function(k){
         const item  = reduced[k];
         return {
             wine_age: item.age,
             score: item.score/item.count,
         }
     })

     console.log(result);

How would I go about finding the average wine score per wine age?我将如何找到每个酒龄的平均葡萄酒分数?

You could group the objects in sub-arrays by age, then reduce the sub-arrays into single objects with the average score:您可以按年龄将子数组中的对象分组,然后将子数组减少为具有平均分数的单个对象:

 const input = [ { age: "113", score: "84.46" }, { age: "113", score: "88.23" }, { age: "112", score: "84.46" }, { age: "113", score: "10.58" }, ]; const result = input .sort((a, b) => a.age - b.age) .reduce( (acc, cur, i, { [i - 1]: last }) => cur.age === last?.age ? Object.assign([...acc], { [acc.length - 1]: [...acc[acc.length - 1], cur], }) : [...acc, [cur]], [] ) .map((x) => ({ age: x[0].age, score: x.reduce((a, b) => a + Number(b.score), 0) / x.length, })); console.log(result);

Here's one way to get it.这是获取它的一种方法。 You'll end up with an object of age:average pairs:你最终会得到一个 age:average 对的对象:

let grps={} 
data.forEach(g => grps.hasOwnProperty(g.age)? // first we set up the age -> array of scores object
     grps[g.age].push(+g.score) : grps[g.age] = [+g.score]),
 avgs = Object.assign(...Object.entries(grps) // then we take that object and calculate the avg based on the total score tally / number of scores
     .map(g=>({[g[0]]:
     (g[1].reduce((b,a)=> b+a)/grps[g[0]].length).toFixed(2)}))) // reduce is a perfect vehicle for tallying up arrays of numbers.

 let data = [ { age: "113", score: "84.46" }, { age: "113", score: "88.23" }, { age: "112", score: "84.46" }, { age: "113", score: "10.58" }, ] let grps={}, s = data.forEach(g=>grps.hasOwnProperty(g.age)?grps[g.age].push(+g.score) : grps[g.age] = [+g.score]), avgs = Object.assign(...Object.entries(grps).map(g=>({[g[0]]:(g[1].reduce((b,a)=> b+a)/grps[g[0]].length).toFixed(2)}))) console.log(avgs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM