英文:
Working with Map, Sum, mean using loadash
问题
// 背景
// 我有以下数据集
let animals =
[
{ id: 1, attributes: [{ title: 'cat', score: 3, weight: 30 }] },
{ id: 2, attributes: [{ title: 'cat', score: 4, weight: 22 }] },
{ id: 3, attributes: [{ title: 'dog', score: 5, weight: 26 }] },
{ id: 4, attributes: [{ title: 'dog', score: 5, weight: 22 }] }
]
// 我的要求是将其转换为以下形式
let animals =
[
{ animal: 'cat', avg_score: 3.5, avg_weight: 26 },
{ animal: 'dog', avg_score: 5, avg_weight: 24 }
]
// 其中 avg_score 和 avg_weight 应该是相应标题的分数和重量的平均值。
// 阅读 lodash 的文档后,我能够发现以下事项:
// 1. 我们需要使用 _.groupBy() 函数按标题分组
// 2. 我们需要使用 _mean() 函数来计算平均值
// 我无法弄清楚如何将这两者结合起来。我迄今为止尝试的方法如下:
const answer = _(animals)
.groupBy('attributes.title')
.map(() => ({
title: attributes.title,
score: _.mean(attribute.score),
weight: _.mean(attribute.weight),
}))
.value();
console.log("主数据:" + answer);
// 但是,由于标题、分数和重量是子项,我们需要某种循环来迭代并获取相应行的实体。
// 例如,分配应该是类似 `title: row.attributes.title` 这样的东西,其中 row 是循环中来自迭代的引用。
// 有人能帮助解决这个问题吗?
你的代码存在一些语法错误和逻辑问题。我帮你做了修正,这里是修改后的代码:
// 导入 lodash 库
const _ = require('lodash');
// 数据集
let animals =
[
{ id: 1, attributes: [{ title: 'cat', score: 3, weight: 30 }] },
{ id: 2, attributes: [{ title: 'cat', score: 4, weight: 22 }] },
{ id: 3, attributes: [{ title: 'dog', score: 5, weight: 26 }] },
{ id: 4, attributes: [{ title: 'dog', score: 5, weight: 22 }] }
];
// 使用 lodash 来对数据进行转换
const transformedAnimals = _.chain(animals)
.groupBy((animal) => animal.attributes[0].title)
.map((groupedAnimals, animal) => {
const avg_score = _.meanBy(groupedAnimals, (a) => a.attributes[0].score);
const avg_weight = _.meanBy(groupedAnimals, (a) => a.attributes[0].weight);
return { animal, avg_score, avg_weight };
})
.value();
// 打印转换后的数据
console.log(transformedAnimals);
这段代码修复了语法错误,并使用 lodash 函数来正确地对数据进行分组和计算平均值。
英文:
Background
I've the following data set with me
let animals =
[
{id:1, attributes:[{ title:'cat',score:3, weight:30 }]},
{id:2, attributes:[{ title:'cat',score:4, weight:22 }]},
{id:3, attributes:[{ title:'dog',score:5, weight:26 }]}
{id:4, attributes:[{ title:'dog',score:5, weight:22 }]}
]
My requirement is to make this look like this:
let animals =
[
{ animal:'cat',avg_score:3.5, avg_weight:26 },
{ animal:'dog',avg_score:5, avg_weight:24 }
]
Where the avg_score and avg_weight should be the average of the score and weight for the respective title.
Reading the documentation of loadash, I was able to figure out that,
- We need to use _.groupBy() function to group by title
- we need to use _mean() function to take the average
I'm unable to figure out how to get this done together. What I tried so far-
const answer = _( animals )
.groupBy( 'attributes.title' )
.map( () => ( {
title: attributes.title,
score: _.mean(attribute.score),
weight: _.mean(attribute.weight),
} ) )
.value();
console.log( "Master Data : " + answer );
However, since the title, score, and weight are child items and we need some kind of a loop to iterate and get the corresponding row's entity, i'm unable to process further. Example, the assignment should be something like 'title' : row.attributes.title
where row is reference of the iteration coming form the loop.
Can someone please help out to unfold this?
答案1
得分: 3
使用普通的ES6:
对于每个动物条目,使用reduce来保持得分、重量和计数的累积总和。然后根据总和和计数来计算平均值。
const animals = [
{"id": 1, "attributes": [{"title": "cat", "score": 3, "weight": 30}]},
{"id": 2, "attributes": [{"title": "cat", "score": 4, "weight": 22}]},
{"id": 3, "attributes": [{"title": "dog", "score": 5, "weight": 26}]},
{"id": 4, "attributes": [{"title": "dog", "score": 5, "weight": 22}]
}];
const result = Object.values(animals.reduce((accumulator, {attributes: [{title, score, weight}]}) => {
const entry = accumulator[title] ??= { animal: title, count: 0, totalScore: 0, totalWeight: 0 };
entry.count++;
entry.totalScore += score;
entry.totalWeight += weight;
return accumulator;
}, {})).map(({ animal, count, totalScore, totalWeight }) => ({
animal,
avg_score: totalScore / count,
avg_weight: totalWeight / count
}));
console.log(result);
这段代码会计算每种动物的平均得分和平均重量。
英文:
With plain ES6:
For each animal entry, use reduce to keep a running total of score, weight, and count. Then calculate the averages as total/count.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const animals = [{"id":1,"attributes":[{"title":"cat","score":3,"weight":30}]},{"id":2,"attributes":[{"title":"cat","score":4,"weight":22}]},{"id":3,"attributes":[{"title":"dog","score":5,"weight":26}]},{"id":4,"attributes":[{"title":"dog","score":5,"weight":22}]}]
const r = Object.values(animals.reduce((a,
{attributes:[{title,score,weight}]},o)=>(
o=(a[title]??={animal:title, count:0, totalScore:0, totalWeight:0}),
o.count++, o.totalScore+=score, o.totalWeight+=weight, a),{}))
.map(({animal,count,totalScore,totalWeight})=>
({animal, avg_score:totalScore/count, avg_weight:totalWeight/count}))
console.log(r)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论