2

I have an array of object like this.

[{"x":"Apr","y":34},{"x":"May","y":34},{"x":"May","y":30},{"x":"May","y":33},{"x":"May","y":26},{"x":"May","y":32},{"x":"May","y":29},{"x":"May","y":32},{"x":"May","y":24},{"x":"May","y":46},{"x":"May","y":43},{"x":"May","y":46},{"x":"May","y":41},{"x":"May","y":40},{"x":"May","y":37},{"x":"May","y":40},{"x":"May","y":40},{"x":"May","y":42},{"x":"May","y":41},{"x":"May","y":43},{"x":"May","y":43},{"x":"May","y":42},{"x":"May","y":42},{"x":"May","y":44},{"x":"May","y":44},{"x":"May","y":46},{"x":"May","y":46},{"x":"May","y":47},{"x":"May","y":47},{"x":"May","y":48},{"x":"May","y":48},{"x":"May","y":48},{"x":"Jun","y":48},{"x":"Jun","y":49},{"x":"Jun","y":49}]

if the key is duplicate then all values will be averaged like below.

[{"x":"Apr","y":34},{"x":"May","y":41.5},{"x":"Jun","y":46.2}]

I have tried taking reference of this link but its not working. Calculate average of duplicates in a javascript array of objects

1
  • Could you elaborate on how the solution you tried to use didn't work? Did you get an error? Did the array not reduce? Did the average values output as not average? It would also help if you edited your question and included the code you attempted to implement. Commented Apr 30, 2021 at 12:50

2 Answers 2

4

const arr = [{"x":"Apr","y":34},{"x":"May","y":34},{"x":"May","y":30},{"x":"May","y":33},{"x":"May","y":26},{"x":"May","y":32},{"x":"May","y":29},{"x":"May","y":32},{"x":"May","y":24},{"x":"May","y":46},{"x":"May","y":43},{"x":"May","y":46},{"x":"May","y":41},{"x":"May","y":40},{"x":"May","y":37},{"x":"May","y":40},{"x":"May","y":40},{"x":"May","y":42},{"x":"May","y":41},{"x":"May","y":43},{"x":"May","y":43},{"x":"May","y":42},{"x":"May","y":42},{"x":"May","y":44},{"x":"May","y":44},{"x":"May","y":46},{"x":"May","y":46},{"x":"May","y":47},{"x":"May","y":47},{"x":"May","y":48},{"x":"May","y":48},{"x":"May","y":48},{"x":"Jun","y":48},{"x":"Jun","y":49},{"x":"Jun","y":49}];

const averages = [...arr
  // get list of month/values
  .reduce((map, { x, y }) => map.set(x, [...(map.get(x) || []), y]), new Map) ]
  // get list of month/average
  .map(([x, y]) => ({ x, y: y.reduce((sum, val) => sum + val, 0) / y.length }));
  
  
console.log(averages);

Sign up to request clarification or add additional context in comments.

Comments

0

You can use Array.reduce, Object.values and Array.map as shown below

let data = [{"x":"Apr","y":34},{"x":"May","y":34},{"x":"May","y":30},{"x":"May","y":33},{"x":"May","y":26},{"x":"May","y":32},{"x":"May","y":29},{"x":"May","y":32},{"x":"May","y":24},{"x":"May","y":46},{"x":"May","y":43},{"x":"May","y":46},{"x":"May","y":41},{"x":"May","y":40},{"x":"May","y":37},{"x":"May","y":40},{"x":"May","y":40},{"x":"May","y":42},{"x":"May","y":41},{"x":"May","y":43},{"x":"May","y":43},{"x":"May","y":42},{"x":"May","y":42},{"x":"May","y":44},{"x":"May","y":44},{"x":"May","y":46},{"x":"May","y":46},{"x":"May","y":47},{"x":"May","y":47},{"x":"May","y":48},{"x":"May","y":48},{"x":"May","y":48},{"x":"Jun","y":48},{"x":"Jun","y":49},{"x":"Jun","y":49}]
    

const formatData = (data) => {
  return Object.values(data.reduce((res, obj) => {
    //check if the object already exists in the res object
    //if already available then add the y value of the current
    //object to the y value of the object present in res
    if (res[obj.x]) {
      res[obj.x].y += obj.y;
      res[obj.x].count += 1;
    } else {
    //If the object is not present then add the current object and the count as 1
      res[obj.x] = { 
        ...obj,
        count: 1
      };
    }
    return res
    //then loop through the array and calculate the avg
  }, {})).map(obj => ({
    x: obj.x,
    y: obj.y / obj.count
  }));
}
console.log(formatData(data));
.as-console-wrapper {
  max-height: 100% !important;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.