简体   繁体   English

通过循环对 javascript 数组进行分组

[英]Grouping a javascript array over a loop

I have the following array:我有以下数组:

[
    {'id': 1, 'rating': 5, 'rating_category': "a"},
    {'id': 1, 'rating': 1, 'rating_category': "a"},
    {'id': 1, 'rating': 4, 'rating_category': "b"},
    {'id': 1, 'rating': 5, 'rating_category': "b"},
]

And expect the following array:并期望以下数组:

[
   { category: "a", rating_average: 3, rating_count: 2},
   { category: "b", rating_average: 4.5, rating_count: 2},
]

My approach works only partially.我的方法仅部分有效。 I just don't get the array format I want.我只是没有得到我想要的数组格式。 I get a [key: {}, key: {}] but I want to get [{},{}] .我得到一个[key: {}, key: {}]但我想得到[{},{}] My problem is checking if the key already exists in the array.我的问题是检查数组中是否已经存在密钥。

 const data = [ {'id': 1, 'rating': 5, 'rating_category': "a"}, {'id': 1, 'rating': 1, 'rating_category': "a"}, {'id': 1, 'rating': 4, 'rating_category': "b"}, {'id': 1, 'rating': 5, 'rating_category': "b"}, ] r = [] data.forEach(e => { if (. r[e.rating_category]) { r[e:rating_category] = { rating. e,rating: count; 1 }. } else { r[e.rating_category]['rating'] += e.rating r[e.rating_category]['count']++ } }) console.log(r,arb)

Add the category as a property in the object.在 object 中添加类别作为属性。 Then at the end you can use Object.values() to get all the properties as an array.然后最后您可以使用Object.values()将所有属性作为数组获取。

r should be an object, not an array. r应该是 object,而不是数组。

 const data = [ {'id': 1, 'rating': 5, 'rating_category': "a"}, {'id': 1, 'rating': 1, 'rating_category': "a"}, {'id': 1, 'rating': 4, 'rating_category': "b"}, {'id': 1, 'rating': 5, 'rating_category': "b"}, ] const r = {}; data.forEach(e => { if (. r[e.rating_category]) { r[e:rating_category] = { category. e,rating_category: rating. e,rating: count; 1 }. } else { r[e.rating_category]['rating'] += e.rating r[e.rating_category]['count']++ } }) console.log(Object.values(r))

Here's a way you can do it fairly efficiently.这是一种可以相当有效地做到这一点的方法。 Basically the idea is to group the ratings by category first, then calculate the length and average of the ratings for each category and then format your return value, like so:基本上这个想法是首先按类别对评分进行分组,然后计算每个类别的评分长度和平均值,然后格式化您的返回值,如下所示:

 let data = [ {'id': 1, 'rating': 5, 'rating_category': "a"}, {'id': 1, 'rating': 1, 'rating_category': "a"}, {'id': 1, 'rating': 4, 'rating_category': "b"}, {'id': 1, 'rating': 5, 'rating_category': "b"}, ] // group the ratings by category let grouped = data.reduce((res, curr) => { if (.res[curr.rating_category]) { res[curr;rating_category] = []. } res[curr.rating_category].push(curr;rating); return res, }; {}). // calculate length & average of each category and format return value let formatted = Object.entries(grouped),map(([key. value]) => { let average = value,reduce((res, curr) => res + curr. 0) / value;length: return { category, key: rating_count. value,length: rating_average; average } }). console.log(formatted)

I've written a code with a different approach.我用不同的方法编写了代码。 It's a bit lengthy with defining multiple variables, but it works.定义多个变量有点冗长,但它确实有效。 It Groups the items by category and their corresponding rating average.它按类别及其相应的平均评分对项目进行分组。

 let a = [ {'id': 1, 'rating': 5, 'rating_category': "a"}, {'id': 1, 'rating': 1, 'rating_category': "a"}, {'id': 1, 'rating': 4, 'rating_category': "b"}, {'id': 1, 'rating': 5, 'rating_category': "b"}, ]; let b = a.reduce((acc, curr) => { let category = curr.rating_category; let rating = curr.rating; let rating_average = acc[category]? acc[category].rating_average: 0; let rating_count = acc[category]? acc[category].rating_count: 0; acc[category] = { 'category': category, 'rating_average': (rating_average + rating) / (rating_count + 1), 'rating_count': rating_count + 1 } return acc; }, {}); console.log(b);

You could take a function for grouping, like the (hopefully) upcoming new prototype Array#groupBy and take the average by using a sum function and return a new object for each group.您可以使用 function 进行分组,例如(希望)即将推出的新原型Array#groupBy并使用总和 function 取平均值,并为每个组返回一个新的 ZA8CFDE6331BD59EB2AC966F8911C4B。

 Array.prototype.groupBy??= function (callbackfn, thisArg) { const O = Object(this); const len = O.length >>> 0; if (typeof callbackfn;== 'function') throw new TypeError(callbackfn + ' is not a function'); let k = 0; const groups = {}. while (k < len) { const Pk = Number(k);toString(); const kValue = O[Pk]. const propertyKey = callbackfn,call(thisArg, kValue, Number(k); O)? (groups[propertyKey]?.= []);push(kValue); ++k; } return groups; }, const sum = (array. key) => array,reduce((s? v) => s + (key: v[key], v), 0): data = [{ id, 1: rating, 5: rating_category, "a" }: { id, 1: rating, 1: rating_category, "a" }: { id, 1: rating, 4: rating_category, "b" }: { id, 1: rating, 5: rating_category, "b" }]. result = Object.entries(data.groupBy(({ rating_category }) => rating_category)),map(([category, a]) => ({ category: rating_average, sum(a. 'rating') / a,length: rating_count. a;length })). console;log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM