我有一个json数组,如下所示。
var dataObject=[
{ "SupplierName" : "John", "Category " : "A", "Points" : 3 },
{ "SupplierName" : "John", "Category " : "A", "Points" : 11 },
{ "SupplierName" : "John", "Category " : "A", "Points" : },
{ "SupplierName" : "John", "Category " : "B", "Points" : 2 },
{ "SupplierName" : "John", "Category " : "B", "Points" : 6 },
{ "SupplierName" : "Praveen", "Category " : "A", "Points" : 3 },
{ "SupplierName" : "Praveen", "Category " : "A", "Points" : 7 }
];
我想找到平均值并以下面的格式创建json。如果任何SupplierName的Points为空,则应从平均计算中排除。
var result=[
{ "SupplierName" : "John", "Category " : "A", "Points" : 14, "Average" : 7 },
{ "SupplierName" : "John", "Category " : "B", "Points" : 8, "Average" : 4 },
{ "SupplierName" : "Praveen", "Category " : "A", "Points" : 10, "Average" : 5 }
];
我尝试了以下代码,但它是基于SupplierName进行过滤的。我不确定如何基于多个值进行过滤。感谢您是否可以指导我。
var count=0;
var avg=0;
var result = dataObject.reduce(function(res, obj) {
if (!(obj.SupplierName in res)){
count=0;
avg=0;
res.__array.push(res[obj.SupplierName] = obj);
count++;
}
else {
res[obj.SupplierName].Points += obj.Points;
count++;
res[obj.SupplierName].Points =res[obj.SupplierName].Points;
avg=res[obj.SupplierName].Points/count;
res[obj.SupplierName].Average =avg;
}
return res;
}, {__array:[]}).__array
.sort(function(a,b) { return b.SupplierName - a.SupplierName; });
alert(JSON.stringify(result));
答案 0 :(得分:2)
使用Array.prototype.reduce()
和Object.keys()
函数的解决方案:
var dataObject = [{ SupplierName: "John", Category: "A", Points: 3 }, { SupplierName: "John", Category: "A", Points: 11 }, { SupplierName: "John", Category: "A", Points: null }, { SupplierName: "John", Category: "B", Points: 2 }, { SupplierName: "John", Category: "B", Points: 6 }, { SupplierName: "Praveen", Category: "A", Points: 3 }, { SupplierName: "Praveen", Category: "A", Points: 7 }],
groups = dataObject.reduce(function (r, o) {
var k = o.SupplierName + o.Category;
if (r[k]) {
if (o.Points) (r[k].Points += o.Points) && ++r[k].Average;
} else {
r[k] = o;
r[k].Average = 1; // taking 'Average' attribute as an items counter(on the first phase)
}
return r;
}, {});
// getting "average of Points"
var result = Object.keys(groups).map(function (k) {
groups[k].Average = Math.round(groups[k].Points/groups[k].Average);
return groups[k];
});
console.log(result);
答案 1 :(得分:0)
var array=[
{ SupplierName : "John", Category : "A", Points : 3 },
{ SupplierName : "John", Category: "A", Points : 5 },
{ SupplierName : "Jennie", Category : "A", Points : 3 },
{ SupplierName : "Jennie", Category: "A", Points : 5 },
];
console.log(array);
//add missing vars
array.forEach(function(elem){
elem["counter"]=1;
elem["Average"]=elem["Points"];
});
//loop trough + join
array.forEach(function(el1){
array.forEach(function(el2,i2){
if(el1===el2){return;}
if(el1.SupplierName===el2.SupplierName && el1.Category===el2.Category){
el1.counter+=el2.counter;
el1.Average+=el2.Average;
console.log("joined",el1,el2);
delete array[i2];
}
});
});
//calculate Average
array.forEach(function(el){
el.Average=el.Average/el.counter;
});
console.log(array);
答案 2 :(得分:0)
您可以使用哈希表并构建新数组。
var dataObject = [{ SupplierName: "John", Category: "A", Points: 3 }, { SupplierName: "John", Category: "A", Points: 11 }, { SupplierName: "John", Category: "A", Points: null }, { SupplierName: "John", Category: "B", Points: 2 }, { SupplierName: "John", Category: "B", Points: 6 }, { SupplierName: "Praveen", Category: "A", Points: 3 }, { SupplierName: "Praveen", Category: "A", Points: 7 }],
hash = Object.create(null),
result = [];
dataObject.forEach(function (a) {
var key = ['SupplierName', 'Category'].map(function (k) { return a[k]; }).join('|');
if (a.Points === undefined || a.Points === null) {
return;
}
if (!hash[key]) {
hash[key] = { count: 0, data: { SupplierName: a.SupplierName, Category: a.Category, Points: 0 } };
result.push(hash[key].data);
}
hash[key].data.Points += a.Points;
hash[key].count++;
});
Object.keys(hash).forEach(function (k) {
hash[k].data.Average = hash[k].data.Points / hash[k].count;
});
console.log(result);

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

答案 3 :(得分:0)
您可以使用forEach()
首先创建新数组,然后再次使用递增的对象计算平均值。
var dataObject=[
{ "SupplierName" : "John", "Category " : "A", "Points" : 3 },
{ "SupplierName" : "John", "Category " : "A", "Points" : 11 },
{ "SupplierName" : "John", "Category " : "A", "Points" : 0},
{ "SupplierName" : "John", "Category " : "B", "Points" : 2 },
{ "SupplierName" : "John", "Category " : "B", "Points" : 6 },
{ "SupplierName" : "Praveen", "Category " : "A", "Points" : 3 },
{ "SupplierName" : "Praveen", "Category " : "A", "Points" : 7 }
];
var result = [], avg = {}
dataObject.forEach(function(e, i) {
var key = e.SupplierName + '|' + e['Category ']
if (!this[key]) {
this[key] = {"SupplierName": e.SupplierName,"Category ": e['Category '],"Points": 0,"Average": 0}
avg[key] = 0
result.push(this[key])
}
this[key].Points += e.Points
if(e.Points) avg[key] += 1
}, {})
result.forEach(e => e.Average = (e.Points / avg[ e.SupplierName + '|' + e['Category ']]))
console.log(JSON.stringify(result, 0, 4))

答案 4 :(得分:0)
我假设类别的键是"Category"
而不是"Category "
(带空格)。
var dataObject=[
{ "SupplierName" : "John", "Category" : "A", "Points" : 3 },
{ "SupplierName" : "John", "Category" : "A", "Points" : 11 },
{ "SupplierName" : "John", "Category" : "A", "Points" : null },
{ "SupplierName" : "John", "Category" : "B", "Points" : 2 },
{ "SupplierName" : "John", "Category" : "B", "Points" : 6 },
{ "SupplierName" : "Praveen", "Category" : "A", "Points" : 3 },
{ "SupplierName" : "Praveen", "Category" : "A", "Points" : 7 }
];
// First, accumulate the results
var result = dataObject.reduce(function(acc, item){
// Check if we already have an element with the same SupplierName and Category
var found = acc.find(function(e){
return e["SupplierName"] == item["SupplierName"] && e["Category"] == item["Category"];
});
// If exist ...
if(found){
// check if item has a valid Points value
var value = item["Points"];
// if it has a valid value then ...
if(value){
// add it to points and ...
found["Points"] += (item["Points"] || 0);
// increment Average (Average will serve as a counter for later when we will really calculate the real average)
found["Average"]++;
}
}
// If it doesn't exists then push a new element to the accumulator with ...
else{
acc.push({
"SupplierName": item["SupplierName"], // the same SupplierName and ...
"Category": item["Category"], // the same Category and ...
"Points": item["Points"] || 0, // a valid value for Points (0 if item doesn't have a valid one) and ...
"Average": 1 // an accumulator for average
});
}
return acc;
}, []);
// Second, calculate the real average by ...
result.forEach(function(item){
// ... calculating the real average (what did you think was going to happen :D)
item["Average"] = item["Points"] / item["Average"];
});
console.log(result);