计算 javascript 对象数组中重复项的平均值
Calculate average of duplicates in a javascript array of objects
我有一个对象数组:
[
{"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"}
]
我正在尝试按平均价格汇总重复项。
所以识别重复行的关键是除价格之外的所有属性,这些属性必须按平均值聚合。
在上面的数据中,例如第5行和第7行:
5) "market": "Butha-Buthe","commodity": 55,"price": "66","month": "04","year": "2017"
7) "market": "Butha-Buthe","commodity": 55,"price": "65","month": "04","year": "2017"
是重复的,我想合并它们并取其价格的平均值。
我正在尝试使用 reduce 函数,但我不知道如何识别重复值,尤其是在它们未排序的情况下。
我 post 代码,但它没用,因为我无法理解如何使用 reduce 识别重复项:
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"}
];
var avg = data.reduce(function(result, current) {
console.log(result,current);
if(!result){
result=current;
}
else {
if(result.market==current.market){
console.log(current.market);
}
}
});
这是一个 jsfiddle,我试图在其中了解 reduce 函数的工作原理:
https://jsfiddle.net/brainsengineering/7tmdx0kg/7/
您可以将这些值插入到一个新数组中,如果它已经存在则合并:
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;
您可以为所需的属性采用组合键,并将 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; }
通过将它们添加到您的 reduce
调用中的数组,将每个项目的价格组合在一起。您可以跟踪哪些项目在同一功能中重复。然后对重复项目使用循环来计算平均值。
请注意,我必须将您的价格 74,99
更改为 74.99
才能更轻松地解析。如果这在您的用例中很重要,您可能需要某种 localization/globalization 库。
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);
我有一个对象数组:
[
{"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"}
]
我正在尝试按平均价格汇总重复项。
所以识别重复行的关键是除价格之外的所有属性,这些属性必须按平均值聚合。
在上面的数据中,例如第5行和第7行:
5) "market": "Butha-Buthe","commodity": 55,"price": "66","month": "04","year": "2017"
7) "market": "Butha-Buthe","commodity": 55,"price": "65","month": "04","year": "2017"
是重复的,我想合并它们并取其价格的平均值。
我正在尝试使用 reduce 函数,但我不知道如何识别重复值,尤其是在它们未排序的情况下。
我 post 代码,但它没用,因为我无法理解如何使用 reduce 识别重复项:
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"}
];
var avg = data.reduce(function(result, current) {
console.log(result,current);
if(!result){
result=current;
}
else {
if(result.market==current.market){
console.log(current.market);
}
}
});
这是一个 jsfiddle,我试图在其中了解 reduce 函数的工作原理: https://jsfiddle.net/brainsengineering/7tmdx0kg/7/
您可以将这些值插入到一个新数组中,如果它已经存在则合并:
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;
您可以为所需的属性采用组合键,并将 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; }
通过将它们添加到您的 reduce
调用中的数组,将每个项目的价格组合在一起。您可以跟踪哪些项目在同一功能中重复。然后对重复项目使用循环来计算平均值。
请注意,我必须将您的价格 74,99
更改为 74.99
才能更轻松地解析。如果这在您的用例中很重要,您可能需要某种 localization/globalization 库。
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);