-
-
Save wdiasvargas/10282eee7f93d65ed5a58f365b321809 to your computer and use it in GitHub Desktop.
'use strict' | |
/**/ | |
function moda (arr) { | |
return ((arr.sort((a, b) => | |
(arr.filter(v => v === a).length) - (arr.filter(v => v === b).length)) | |
).pop()) | |
} | |
module.exports = moda | |
console.log(moda([1,2,3,4,5])) //amodal nao tem moda(nao deveria aparecer nada) | |
console.log(moda([1,2,3,4,5,5])) //modal tem moda(5) pois aparece mais vezes | |
console.log(moda([1,2,3,3,4,4,5,5])) //plurimodal tem mais de 1 moda(3,4,5)pois aparecem mais vezes |
Expliquei parte a parte aqui http://nomadev.com.br/node-js-aprendendo-um-pouco-de-funcional-com-estatistica/
Ficou boa a explicação @lukaswilkeer @cyberglot @haskellcamargo @wdiasvargas ???
Esse reduce da @cyberglot humilhou hein! Eu não tenho nem a lógica de pensar dessa forma AINDA.
Apenas uma sugestão:
const toArray = obj => Object.keys(obj).map(key => obj[key]);
const summarize = numbers => toArray(numbers.reduce(summarizeFn, {}));
const summarizeFn = function(summary, num) {
summary[num] = summary[num]
? { num, count: summary[num].count + 1 }
: { num, count: 1 }
return summary;
};
const findMode = summary => summary.reduce(findModeFn, 0);
const findModeFn = (max, { count }) => count > max ? count : max;
const filterMode = (summary, mode) => summary.filter(({ count }) => count == mode);
const getValues = items => items.map(({ num }) => num);
const mode = function(numbers) {
const summary = summarize(numbers);
const mode = findMode(summary);
const modeItems = filterMode(summary, mode);
return modeItems.length == summary.length ? [] : getValues(modeItems);
}
console.log(mode([])); // []
console.log(mode([1, 2, 3, 4, 5])); // []
console.log(mode([1, 1, 3, 3, 4, 4, 5, 5])); // []
console.log(mode([1, 1, 3, 4, 5])); // [1]
console.log(mode([1, 3, 3, 3, 5])); // [3]
console.log(mode([1, 1, 3, 3, 4, 5])); // [1, 3]
MUITO BOM @ribaptista
Só no final o [] tem q retornar 0 por ser amodal, mas ficou MUITO SIMPLES e legível!
Muito obrigado, @suissa!
Mas eu acredito que num cenário real seja desejável a função retornar []
ao invés de zero quando o input é amodal. Assim a função é consistente quanto ao tipo de dado do retorno (sempre um array). Facilita para o código que chamar essa função lidar sempre com o mesmo tipo de retorno.
Escrevi um e ficou uma merda rs
const histogram = arr => arr.reduce( (result, item) => {
result[item] = (result[item] || 0) + 1
return result
}, {})
const pairs = obj => Object.keys(obj).map( key => [key, obj[key]] )
function mode(arr) {
let result = pairs(histogram(arr))
.sort( (a,b) => b[1] - a[1] )
.filter( (item, index, source) => item[1] === source[0][1] )
.map( item => item[0] )
return result.length === arr.length ? [] : result
}
console.log( mode([1,2,3,4,5]) )
console.log( mode([1,2,3,4,5,5]) )
console.log( mode([1,2,3,4,4,5,5]) )
Sobre "código puramente funcional", é só extrair os constructos imperativos em funções? Pois em baixo nível sempre será imperativo... Dá na mesma...
@lukaswilkeer mas ramda é uma boa opção para projetos, e vc pode carregar só o que precisa.
@suissa 😉