计算对象的javascript数组中重复项的平均值

时间:2019-03-06 18:58:23

标签: javascript arrays json mapreduce aggregate

我有一个对象数组:

public class Circle

    private int radius;

    public Circle(int r) 
    {
        radius = r;
    }

    public int getRadius()
    {
        return radius;
    }

    public double getArea()
    {
        return Math.PI * radius * radius;  
    }

}

我正在尝试按平均价格汇总重复项

因此,用于标识重复行的关键是除 price 之外的所有属性,这些属性必须按平均值进行汇总。

在上面的数据中,例如第5行和第7行:

[
{"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"}
]

是重复项,我想将它们合并并取其价格平均值。

我试图使用 reduce 函数,但是我不知道如何识别重复的值,尤其是如果未对它们进行排序的话。

我发布了代码,但是它没用,因为我不明白如何使用reduce识别重复项:

5) "market": "Butha-Buthe","commodity": 55,"price": "66","month": "04","year": "2017"
7) "market": "Butha-Buthe","commodity": 55,"price": "65","month": "04","year": "2017"

这里是一个jsfiddle,我试图了解reduce函数的工作原理: https://jsfiddle.net/brainsengineering/7tmdx0kg/7/

3 个答案:

答案 0 :(得分:2)

您可以为所需属性使用组合键,并将price格式替换为数字可分析格式。

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; }

答案 1 :(得分:1)

通过将它们添加到您的reduce调用数组中,将每个项目的价格分组在一起。您可以跟踪在同一功能中重复的项目。然后使用循环遍历重复项来计算平均值。

请注意,我必须将您的价格74,99更改为74.99才能更轻松地进行解析。如果这对您的用例至关重要,则可能需要某种本地化/全球化库。

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"}
];

function parsePrice(str) {
  // TODO: localization
  return +str;
}

function formatPrice(num) {
  return num.toFixed(2);
}

function getHashKey(item) {
  return JSON.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);

答案 2 :(得分:0)

您可以将值插入到新数组中并合并(如果已经存在):

 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(const group of result)
   group.price = group.prices.reduce((a, b) => a + b, 0) / group.prices.length;