skip to Main Content

I have a 2d array which contains a list of series with title, rating, and time spent watching. For example:

let seriesList = [["Squid Game", 3.5, "4 days"], ["Squid Game", 2.5, "3 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]];

A series can appear multiple times with a different rating. I would like to calculate the average rating for each series (and get another 2d array with each series appearing only once).

So far, I used reduce() on the array in order to do the sum of all the ratings, but I can’t figure out how to get the number of ratings so I can divide by it.

let seriesList = [["Squid Game", 3.5, "4 days"], ["Squid Game", 2.5, "3 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]]; // example of values in my array, but it's actually much longer and it will change with each new series i watch
    
let seriesListAverage = Object.values(
    seriesList.reduce((accumulator, currentValue) => {

      if (accumulator[currentValue[0]]) {
        accumulator[currentValue[0]][1] += currentValue[1]; // do the sum of all ratings
      }
      else {
        accumulator[currentValue[0]] = currentValue;
      }
      return accumulator;
    }, {})
);

console.log(seriesListAverage); // Result: [["Squid Game", 6, "4 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]]

// Expected result: [["Squid Game", 3, "4 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]]

(If it matters, the script is written in Apps Script, I get the values for seriesList from a sheet of my Sheets file, and I print the result into another sheet. That’s why I need a 2d array.)

2

Answers


  1. You could group first and then get the average.

    const
        series = [["Squid Game", 3.5, "4 days"], ["Squid Game", 2.5, "3 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]],
        result = Object
            .values(Object.groupBy(series, ([serie]) => serie))
            .map(group => [group[0][0], group.reduce((t, [_, r]) => t + r, 0) / group.length]);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. function listAvg() {
      const arr = [["Squid Game", 3.5, "4 days"], ["Squid Game", 2.5, "3 days"], ["Buffy the Vampire Slayer", 5, "32 days"], ["The Fosters", 3, "5 days"]];
      let obj = arr.reduce((a,r,i) => {
        let p = r[0];
        if(!a.hasOwnProperty(p)) {
          a[p] = {row:r,count:1};
          a.pA.push(p);
        } else {
          a[p]["row"][1] += r[1];
          a[p]["count"] += 1;
        }
        return a;
      },{pA:[]});
      obj.pA.forEach(p => {
        obj[p]["row"][1] = obj[p]["row"][1]/obj[p]["count"];
        obj[p]["row"].splice(2,1);//remove last element
        Logger.log(JSON.stringify(obj[p].row));
      })
      const end = "is near"
    }
    
    Execution log
    1:01:03 PM  Notice  Execution started
    1:00:58 PM  Info    ["Squid Game",3] //Name,Average
    1:00:58 PM  Info    ["Buffy the Vampire Slayer",5]
    1:00:58 PM  Info    ["The Fosters",3]
    1:01:05 PM  Notice  Execution completed
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search