Javascript 使用lodash查找平均值的最有效方法
我有一个对象数组,对象的数量是可变的-Javascript 使用lodash查找平均值的最有效方法,javascript,underscore.js,lodash,Javascript,Underscore.js,Lodash,我有一个对象数组,对象的数量是可变的- var people = [{ name: john, job: manager, salary: 2000 }, { name: sam, job: manager, salary: 6000 }, { name: frodo, job: janitor }]; 找到使用lodash的所有经理的平均工资的最优雅的方法是什么?(我假设我们必须检查对象是否为经理,以及对象是否具有薪资属性) 我在想下面的话- _(pe
var people = [{
name: john,
job: manager,
salary: 2000
},
{
name: sam,
job: manager,
salary: 6000
},
{
name: frodo,
job: janitor
}];
找到使用lodash的所有经理的平均工资的最优雅的方法是什么?(我假设我们必须检查对象是否为经理,以及对象是否具有薪资属性)
我在想下面的话-
_(people).filter(function(name) {
return name.occupation === "manager" && _(name).has("salary");}).pluck("salary").reduce(function(sum,num) { return sum+num });
但我不确定这是否是正确的方法。“高效”是一个非常模糊的术语。说到“高效”,你可以考虑性能、可读性、简洁性等等。我认为最具可读性和简洁性的解决方案是:
_(people).filter({ job: 'manager'}).filter('salary').reduce(function(a,m,i,p) {
return a + m.salary/p.length;
},0);
最快的解决方案是根本不使用loadash、任何库、任何过滤器
、减少
方法。将用于循环:
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;
var总和=0;
var计数=0;
对于(变量i=0,ii=people.length;i
我认为在大多数情况下,对于客户端开发来说,可读性比性能更重要,因此我认为第一个变体是最“有效的”。我不知道Lowdath,但也许一个简单的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
这将传递一个要减少的对象作为累加器,该累加器具有三个属性:工资总额、工资计数和迄今为止的平均值。它对所有对象进行迭代,将工资相加,计算有多少工资,并计算每次迭代的平均值。最终,它返回该对象(累加器),并读取平均属性
调用单个内置方法应该比调用4个本机函数更快(即更高效)。“优雅”在旁观者的眼里
顺便说一句,对象文字中有错误,应该是:
var people = [{
name: 'john',
job: 'manager',
salary: 2000
},
{
name: 'sam',
job: 'manager',
salary: 6000
},
{
name: 'frodo',
job: 'janitor'
}];
我能想到的最干净(优雅)的方式是:
var salariesOfManagers = _(people).filter({job: 'manager'}).filter('salary').pluck('salary');
var averageSalary = salariesOfManagers.sum() / salariesOfManagers.value().length;
它取项目之和,然后除以项目数,这几乎就是平均数的定义
太糟糕了,如果你想让它整洁一行,代码将变得不那么清晰。使用功能更强大的lodash
版本(lodash fp
)和es2015
,你可以使用箭头功能和自动咖喱来获得更灵活、更功能化的解决方案
function average(acc, ele, index) {
return (acc + ele) / (index + 1);
}
var result = _.chain(people)
.filter('job', 'manager')
.map('salary')
.reduce( average )
.value();
你可以把它放在一行难看的单字里:
const result = _.flow(_.filter(['job', 'manager']),
e => _.sumBy('salary', e) / _.countBy(_.has('salary'), e).true)(people);
或者您可以创建一个整洁的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);
使用和ES2016/ES6,可以以更有效的方式完成
const avg = flow(
filter({job: 'manager'}),
map('salary'),
mean
)
console.log(avg(people))
你所做的是
1.获取所有对象的“管理器”类型
2.从中提取“薪资”属性/字段
3.用均值函数求平均值
下面是一个完整版本的代码,为了方便您,它运行在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))
为什么这里的人都很复杂
const people=[
{名称:'Alejandro',预算:56},
{名称:'Juan',预算:86},
{名称:“佩德罗”,预算:99},
];
const average=u.meanBy(人,(p)=>p.budget);
控制台日志(平均值)代码>
lodash v3:
\uuu.sum(people,'salary')/people.length
(people
不能为空)
lodash v4:
\意思是(人,'salary')
这个代码有效吗?reduce似乎没有找到avg,而是返回了所有工资的总和。除了reduce中的明显错误使其返回的是OP问题中的总和而不是平均值之外,这与他的解决方案有何不同?(真的在问,没有批评的意思)a+m.salary/p.length
-看看p.length
-这使结果平均,而不是总和。@lascort如果你不相信我,你可以自己试试。转到,打开控制台,创建人员
数组,然后复制/粘贴我的解决方案。我并不是说它不起作用,我只是说,在我看来,它似乎与他做的事情相同,但顺序不同。除了他显然在reduce函数中犯了一个错误,但我认为这只是一个输入错误。但我可能弄错了,我不是洛达斯的专家,这就是我为什么这么做的原因asking@lascort问题是“使用lodash找到平均值的最有效方法”。我认为这是最“高效”和优雅的方式。我认为这比他自己的解决方案更清楚。如果有人有更好的想法,他们可以自己写答案。如果我发现他们的解决方案更好,我甚至会删除我的答案代码>。也只适用于v4.*@Stalinko,这使它变得更短,而不是更简单,当你使用IDE时,你可以看到预算的类型(在TypeScript的情况下),或者你可以使用go to declaration,find references等。答案很好,他可以做的是使用p=>p.budget
@Stalinko不完全是,使用arrow方法时,它省略了计算,并使用中间件方法查找“预算”成员,正如Almis所说,箭头使IDE能够查看数据类型。@FredericYesidPeñasánchez让人们决定他们更喜欢什么。无论如何,这两种方法没有太大区别。