Javascript 使用 lodash 查找平均值的最有效方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28213295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
most efficient way to find average using lodash
提问by meajmal
I have an array of objects, the number of objects is variable -
我有一个对象数组,对象的数量是可变的 -
var people = [{
name: john,
job: manager,
salary: 2000
},
{
name: sam,
job: manager,
salary: 6000
},
{
name: frodo,
job: janitor
}];
Whats the most elegant way to find the average of the salaries of all managers using lodash? ( I assume we have to check if an object is manager, as well as if the object has a salary property)
使用 lodash 找到所有经理的平均工资的最优雅的方法是什么?(我假设我们必须检查一个对象是否是经理,以及该对象是否具有工资属性)
I was thinking in the below lines -
我在想以下几行 -
_(people).filter(function(name) {
return name.occupation === "manager" && _(name).has("salary");}).pluck("salary").reduce(function(sum,num) { return sum+num });
But I am not sure if this is the right approach.
但我不确定这是否是正确的方法。
回答by Frederic Yesid Pe?a Sánchez
Why all people gets over-complicated here?
为什么所有人都在这里变得过于复杂?
const people = [
{ name: 'Alejandro', budget: 56 },
{ name: 'Juan', budget: 86 },
{ name: 'Pedro', budget: 99 },
];
const average = _.meanBy(people, (p) => p.budget);
console.log(average);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
As per the docs: https://lodash.com/docs/#meanBy
回答by alexpods
"efficient" is very ambiguous term. Saying "efficient" you can think about performance, or readability, or concisenessand so on. I think the most readableand concisesolution is:
“高效”是一个非常含糊的词。说“高效”,您可以考虑性能、可读性或简洁性等。我认为最易读和简洁的解决方案是:
_(people).filter({ job: 'manager'}).filter('salary').reduce(function(a,m,i,p) {
return a + m.salary/p.length;
},0);
The most fastsolution is do not use loadash, nor any library, nor any filter, reducemethods at all. Use forloop instead:
最快速的解决方案是根本不使用 loadash,也不使用任何库,也不使用任何filter,reduce方法。改用for循环:
var sum = 0;
var count = 0;
for (var i = 0, ii = people.length; i < ii; ++i) {
var man = people[i];
if (typeof man.salary !== 'undefined') {
sum += man.salary;
++count;
}
}
var avg = sum/count;
I think for the client side development readabilityis more important than performancein most cases , so I think first variant is most "efficient".
我认为在大多数情况下,对于客户端开发可读性比性能更重要,所以我认为第一个变体是最“有效”的。
回答by Stalinko
lodash v3:
lodash v3:
_.sum(people, 'salary') / people.length(peoplemustn't be empty)
_.sum(people, 'salary') / people.length(people不能为空)
lodash v4:
lodash v4:
_.meanBy(people, 'salary')
_.meanBy(people, 'salary')
回答by RobG
I don't know about lowdash, but maybe a plain JS solution will help you get there:
我不知道 lowdash,但也许一个普通的 JS 解决方案会帮助你到达那里:
console.log(people.reduce(function(values, obj) {
if (obj.hasOwnProperty('salary')) {
values.sum += obj.salary;
values.count++;
values.average = values.sum / values.count;
}
return values;
}, {sum:0, count:0, average: void 0}).average
); // 4000
This passes an object to reduceas the accumulatorthat has three properties: the sum of salaries, the count of salaries, and the average so far. It iterates over all the objects, summing the salaries, counting how many there are and calculating the average on each iteration. Eventually it returns that object (the accumulator) and the averageproperty is read.
此传递一个目的是减少作为累加器具有三个属性:薪金的总和,薪水的计数,和到目前为止的平均值。它迭代所有对象,汇总工资,计算有多少,并计算每次迭代的平均值。最终它返回该对象(累加器)并读取平均属性。
Calling a single built–in method should be faster (i.e. more efficient) than calling 4 native functions. "Elegant" is in the eye of the beholder. ;-)
调用单个内置方法应该比调用 4 个本机函数更快(即更有效)。“优雅”在旁观者的眼中。;-)
BTW, there are errors in the object literal, it should be:
顺便说一句,对象文字中有错误,应该是:
var people = [{
name: 'john',
job: 'manager',
salary: 2000
},
{
name: 'sam',
job: 'manager',
salary: 6000
},
{
name: 'frodo',
job: 'janitor'
}];
回答by Pax Samana
function average(acc, ele, index) {
return (acc + ele) / (index + 1);
}
var result = _.chain(people)
.filter('job', 'manager')
.map('salary')
.reduce( average )
.value();
回答by AA.
With the more functional lodashversion (lodash-fp) and es2015you can to use arrow functions and auto curry to get a more flexible and functional flavored solution.
使用功能更强大的lodash版本 ( lodash-fp),es2015您可以使用箭头函数和自动咖喱来获得更灵活和功能更强大的解决方案。
You can put it in an ugly one liner:
你可以把它放在一个丑陋的单衬里:
const result = _.flow(_.filter(['job', 'manager']),
e => _.sumBy('salary', e) / _.countBy(_.has('salary'), e).true)(people);
Or you can create a tidy DSL:
或者你可以创建一个整洁的 DSL:
const hasSalary = _.has('salary');
const countWhenHasSalary = _.countBy(hasSalary);
const salarySum = _.sumBy('salary');
const salaryAvg = a => salarySum(a) / countWhenHasSalary(a).true;
const filterByJob = job => _.filter(['job', job]);
const salaryAvgByJob = job => _.flow(filterByJob(job), salaryAvg);
const result = salaryAvgByJob('manager')(people);
回答by Vlad Bezden
Using lodash/fpand ES2016/ES6 it can be done in a more functional way
使用lodash/fp和 ES2016/ES6 可以以更实用的方式完成
const avg = flow(
filter({job: 'manager'}),
map('salary'),
mean
)
console.log(avg(people))
What you do is 1. Get all objects 'manager' type 2. Extract 'salary' property/field from them 3. Find average using mean function
您要做的是 1. 获取所有对象的“经理”类型 2. 从中提取“薪水”属性/字段 3. 使用均值函数求平均值
Here is a full version of code for your convenience that runs on nodejs.
为方便起见,这是在 nodejs 上运行的完整代码版本。
'use strict'
const _ = require('lodash/fp');
const {
flow,
filter,
map,
mean
} = _
const people = [{
name: 'john',
job: 'manager',
salary: 2000
}, {
name: 'sam',
job: 'manager',
salary: 6000
}, {
name: 'frodo',
job: 'janitor'
}];
const avg = flow(
filter({job: 'manager'}),
map('salary'),
mean
)
console.log(avg(people))
回答by Mikael Lepist?
Most clean (elegant) way I could think of was:
我能想到的最干净(优雅)的方式是:
var salariesOfManagers = _(people).filter({job: 'manager'}).filter('salary').pluck('salary');
var averageSalary = salariesOfManagers.sum() / salariesOfManagers.value().length;
It takes sum of items and divides its with number of items, which is pretty much the definition of average.
它取项目的总和并将其除以项目的数量,这几乎是平均值的定义。
Too bad that if you would like to make that to neat one-liner, the code will get less clear to read.
太糟糕了,如果你想把它变成整洁的单行代码,代码会变得不太清晰。

