react example array javascript underscore.js lodash

javascript - example - La forma más eficiente de encontrar el promedio usando lodash.



lodash pluck (8)

"eficiente" es término muy ambiguo. Al decir "eficiente", puedes pensar en el rendimiento , la legibilidad , la concisión, etc. Creo que la solución más legible y concisa es:

_(people).filter({ job: ''manager''}).filter(''salary'').reduce(function(a,m,i,p) { return a + m.salary/p.length; },0);

La solución más rápida es no usar loadash, ni ninguna biblioteca, ni ningún filter , reduce métodos. Utilice for bucle en su lugar:

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;

Creo que para el lado del cliente, la legibilidad del desarrollo es más importante que el rendimiento en la mayoría de los casos, por lo que creo que la primera variante es la más "eficiente".

Tengo una matriz de objetos, el número de objetos es variable -

var people = [{ name: john, job: manager, salary: 2000 }, { name: sam, job: manager, salary: 6000 }, { name: frodo, job: janitor }];

¿Cuál es la manera más elegante de encontrar el promedio de los salarios de todos los gerentes que usan lodash? (Supongo que tenemos que verificar si un objeto es administrador, así como si el objeto tiene una propiedad de salario)

Estaba pensando en las líneas de abajo ...

_(people).filter(function(name) { return name.occupation === "manager" && _(name).has("salary");}).pluck("salary").reduce(function(sum,num) { return sum+num });

Pero no estoy seguro de si este es el enfoque correcto.


¿Por qué toda la gente se complica demasiado aquí?

const people = [ {name: ''Alejandro'', budget: 56}, {name: ''Juan'', budget: 86}, {name: ''Pedro'', budget: 99}]; let average = _.meanBy(people, (p) => p.budget);

Según los documentos: https://lodash.com/docs/#meanBy


Con la versión lodash más funcional ( lodash-fp ) y es2015 puede usar las funciones de flecha y el curry automático para obtener una solución con sabor más flexible y funcional.

Puedes ponerlo en un feo forro:

const result = _.flow(_.filter([''job'', ''manager'']), e => _.sumBy(''salary'', e) / _.countBy(_.has(''salary''), e).true)(people);

O puedes crear un DSL ordenado:

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);


La forma más limpia (elegante) que pude pensar fue:

var salariesOfManagers = _(people).filter({job: ''manager''}).filter(''salary'').pluck(''salary''); var averageSalary = salariesOfManagers.sum() / salariesOfManagers.value().length;

Toma la suma de los ítems y la divide con el número de ítems, que es más o menos la definición de promedio.

Es una lástima que si desea hacer eso de forma sencilla, el código será menos claro para leer.


No sé sobre lowdash, pero tal vez una solución simple de JS te ayude a llegar allí:

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

Esto pasa a un objeto para reducir como el acumulador que tiene tres propiedades: la suma de los salarios, el recuento de los salarios y el promedio hasta el momento. Se itera sobre todos los objetos, sumando los salarios, contando cuántos hay y calculando el promedio en cada iteración. Finalmente, devuelve ese objeto (el acumulador ) y se lee la propiedad promedio .

Llamar a un solo método integrado debe ser más rápido (es decir, más eficiente) que llamar a 4 funciones nativas. "Elegante" está en el ojo del espectador. ;-)

Por cierto, hay errores en el objeto literal, debe ser:

var people = [{ name: ''john'', job: ''manager'', salary: 2000 }, { name: ''sam'', job: ''manager'', salary: 6000 }, { name: ''frodo'', job: ''janitor'' }];


Usando lodash/fp y ES2016 / ES6 se puede hacer de una manera más funcional

const avg = flow( filter({job: ''manager''}), map(''salary''), mean ) console.log(avg(people))

Lo que usted hace es 1. Obtener de todos los objetos tipo "administrador" 2. Extraer propiedad / campo de "salario" de ellos 3. Encontrar el promedio usando la función media

Aquí hay una versión completa del código para su conveniencia que se ejecuta en 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))


lodash v3:

_.sum(people, ''salary'') / people.length people (las people no deben estar vacías)

lodash v4:

_.meanBy(people, ''salary'')


function average(acc, ele, index) { return (acc + ele) / (index + 1); } var result = _.chain(people) .filter(''job'', ''manager'') .map(''salary'') .reduce( average ) .value();