Skip to content Skip to sidebar Skip to footer

Calculate Average Of Duplicates In A Javascript Array Of Objects

I have an array of objects: [ {'market': 'Qacha's nek','commodity': 55,'price': '90','month': '04','year': '2017'}, {'market': 'Mohales Hoek','commodity': 55,'price': '75','month'

Solution 1:

You could take a combined key for the wanted properties and replace the price format to a numerical parsable format.

var data = [{ market: "Qacha's nek", commodity: 55, price: "90", month: "04", year: "2017" }, { market: "Mohales Hoek", commodity: 55, price: "75", month: "04", year: "2017" }, { market: "Mafeteng", commodity: 55, price: "75", month: "04", year: "2017" }, { market: "Maseru", commodity: 55, price: "69", month: "04", year: "2017" }, { market: "Butha-Buthe", commodity: 55, price: "66", month: "04", year: "2017" }, { market: "Leribe", commodity: 55, price: "64", month: "04", year: "2017" }, { market: "Butha-Buthe", commodity: 55, price: "65", month: "04", year: "2017" }, { market: "Thaba-Tseka", commodity: 55, price: "82", month: "04", year: "2017" }, { market: "Thaba-Tseka", commodity: 55, price: "81", month: "04", year: "2017" }, { market: "Maseru", commodity: 55, price: "74,99", month: "04", year: "2017" }],
    keys = ['market', 'commodity', 'month', 'year'],
    count = {},
    result = data.reduce(function (r, o) {
        var key = keys.map(function (k) { return o[k]; }).join('|');
        if (!count[key]) {
            count[key] = { sum: +o.price.replace(',', '.'), data: JSON.parse(JSON.stringify(o)) };
            count[key].data.count = 1;
            r.push(count[key].data);
        } else {
            count[key].sum += +o.price.replace(',', '.');
            count[key].data.price = (count[key].sum / ++count[key].data.count).toString();
        }
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100%!important; top: 0; }

Solution 2:

Group prices together for each item by adding them to an array in your reduce call. You can keep track of which items are duplicated in the same function. Then use loop over the duplicate items to compute the averages.

Note I had to change your price 74,99 to 74.99 to parse more easily. You'll probably want some sort of localization/globalization library if this is critical in your use case.

var data = [
{"market": "Qacha's nek","commodity": 55,"price": "90","month": "04","year": "2017"}, 
{"market": "Mohales Hoek","commodity": 55,"price": "75","month": "04","year": "2017"}, 
{"market": "Mafeteng","commodity": 55,"price": "75","month": "04","year": "2017"}, 
{"market": "Maseru","commodity": 55,"price": "69","month": "04","year": "2017"}, 
{"market": "Butha-Buthe","commodity": 55,"price": "66","month": "04","year": "2017"}, 
{"market": "Leribe","commodity": 55,"price": "64","month": "04","year": "2017"}, 
{"market": "Butha-Buthe","commodity": 55,"price": "65","month": "04","year": "2017"}, 
{"market": "Thaba-Tseka","commodity": 55,"price": "82","month": "04","year": "2017"},
{"market": "Thaba-Tseka","commodity": 55,"price": "81","month": "04","year": "2017"},
{"market": "Maseru","commodity": 55,"price": "74.99","month": "04","year": "2017"}
];

functionparsePrice(str) {
  // TODO: localizationreturn +str;
}

functionformatPrice(num) {
  return num.toFixed(2);
}

functiongetHashKey(item) {
  returnJSON.stringify([item.market, item.commodity, item.month, item.year]);
}

var duplicatedItems = {};
var prices = data.reduce(function(result, current) {
  var key = getHashKey(current);
  if (key in result) {
    result[key].push(parsePrice(current.price));
    duplicatedItems[key] = current;
  } else {
    result[key] = [parsePrice(current.price)];
  }
  return result;
}, {});
var avg = Object.keys(duplicatedItems).map(function(key) {
  var item = duplicatedItems[key];
  var avgPrice = prices[key].reduce(function(acc, price) { return acc + price; }, 0) / prices[key].length;
  return {
    market: item.market,
    commodity: item.commodity,
    price: formatPrice(avgPrice),
    month: item.month,
    year: item.year
  };
});

console.log(avg);

Solution 3:

You could insert the values into a new array and merge if it already exists:

const result = [];

 outer: for(const {  market, commodity,  price, month, year } of input) {
    for(const other of result) {
       if(market === other.market && commodity === other.commodity && month === other.month && year === other.year) {
         other.prices.push(+price);

         continue outer;
       }
    }
    result.push({ market, commodity, prices: [+price], month, year });
 }

 for(constgroup of result)
   group.price = group.prices.reduce((a, b) => a + b, 0) / group.prices.length;

Post a Comment for "Calculate Average Of Duplicates In A Javascript Array Of Objects"