javascript - tablas - Obtener el elemento con la mayor ocurrencia en una matriz
obtener datos de una tabla html javascript (22)
Aquí está mi solución a este problema, pero con números y usando la nueva función ''Establecer''. No es muy eficiente, pero definitivamente me divertí mucho escribiendo esto y admite múltiples valores máximos.
const mode = (arr) => [...new Set(arr)]
.map((value) => [value, arr.filter((v) => v === value).length])
.sort((a,b) => a[1]-b[1])
.reverse()
.filter((value, i, a) => a.indexOf(value) === i)
.filter((v, i, a) => v[1] === a[0][1])
.map((v) => v[0])
mode([1,2,3,3]) // [3]
mode([1,1,1,1,2,2,2,2,3,3,3]) // [1,2]
Por cierto, no use esto para la producción, esto es solo una ilustración de cómo puede resolverlo con las funciones ES6 y Array solamente.
Estoy buscando una manera elegante de determinar qué elemento tiene la mayor ocurrencia ( mode ) en una matriz de JavaScript.
Por ejemplo, en
[''pear'', ''apple'', ''orange'', ''apple'']
el elemento ''apple''
es el más frecuente.
Aquí está mi solución:
function frequent(number){
var count = 0;
var sortedNumber = number.sort();
var start = number[0], item;
for(var i = 0 ; i < sortedNumber.length; i++){
if(start === sortedNumber[i] || sortedNumber[i] === sortedNumber[i+1]){
item = sortedNumber[i]
}
}
return item
}
console.log( frequent([''pear'', ''apple'', ''orange'', ''apple'']))
Como uso esta función como cuestionario para los entrevistadores, publico mi solución:
const highest = arr => (arr || []).reduce( ( acc, el ) => {
acc.k[el] = acc.k[el] ? acc.k[el] + 1 : 1
acc.max = acc.max ? acc.max < acc.k[el] ? el : acc.max : el
return acc
}, { k:{} }).max
const test = [0,1,2,3,4,2,3,1,0,3,2,2,2,3,3,2]
console.log(highest(test))
Con base en la respuesta ES6 + de Emissary , podría usar Array.prototype.reduce
para hacer su comparación (en lugar de ordenar, explotar y potencialmente mutar su matriz), lo que creo que se ve bastante ingenioso.
const mode = (myArray) =>
myArray.reduce(
(a,b,i,arr)=>
(arr.filter(v=>v===a).length>=arr.filter(v=>v===b).length?a:b),
null)
Estoy por defecto en nulo, lo que no siempre te dará una respuesta veraz si null es una opción posible para la que estás filtrando, quizás ese podría ser un segundo argumento opcional
La desventaja, como ocurre con varias otras soluciones, es que no maneja los "estados de dibujo", pero esto aún podría lograrse con una función de reducción ligeramente más complicada.
Esta función es genérica para todo tipo de información. Cuenta la ocurrencia de los elementos y luego regresa la matriz con elementos que ocurren al máximo.
function mode () {
var arr = [].slice.call(arguments);
if ((args.length == 1) && (typeof args[0] === "object")) {
args = args[0].mode();
}
var obj = {};
for(var i = 0; i < arr.length; i++) {
if(obj[arr[i]] === undefined) obj[arr[i]] = 1;
else obj[arr[i]]++;
}
var max = 0;
for (w in obj) {
if (obj[w] > max) max = obj[w];
}
ret_val = [];
for (w in obj) {
if (obj[w] == max) ret_val.push(w);
}
return ret_val;
}
Esta solución puede devolver múltiples elementos de una matriz si ocurren por el mismo tiempo. por ejemplo, una matriz arr = [3,4,3,6,4] tiene dos valores de modo, 3 y 6.
Aquí está la solución,
function find_mode(arr) {
var max = 0;
var maxarr = [];
var counter = [];
var maxarr = [];
arr.forEach(function(){
counter.push(0);
});
for(var i = 0;i<arr.length;i++){
for(var j=0;j<arr.length;j++){
if(arr[i]==arr[j])counter[i]++;
}
}
max=this.arrayMax(counter);
for(var i = 0;i<arr.length;i++){
if(counter[i]==max)maxarr.push(arr[i]);
}
var unique = maxarr.filter( this.onlyUnique );
return unique;
};
function arrayMax(arr) {
var len = arr.length, max = -Infinity;
while (len--) {
if (arr[len] > max) {
max = arr[len];
}
}
return max;
};
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
Este es solo el modo. Aquí hay una solución rápida, no optimizada . Debería ser O (n).
function mode(array)
{
if(array.length == 0)
return null;
var modeMap = {};
var maxEl = array[0], maxCount = 1;
for(var i = 0; i < array.length; i++)
{
var el = array[i];
if(modeMap[el] == null)
modeMap[el] = 1;
else
modeMap[el]++;
if(modeMap[el] > maxCount)
{
maxEl = el;
maxCount = modeMap[el];
}
}
return maxEl;
}
Podrías resolverlo en O (n) complejidad
var arr = [1,3,54,56,6,6,1,6];
var obj = {};
/* first convert the array in to object with unique elements and number of times each element is repeated */
for(var i = 0; i < arr.length; i++)
{
var x = arr[i];
if(!obj[x])
obj[x] = 1;
else
obj[x]++;
}
console.log(obj);//just for reference
/* now traverse the object to get the element */
var index = 0;
var max = 0;
for(var obIndex in obj)
{
if(obj[obIndex] > max)
{
max = obj[obIndex];
index = obIndex;
}
}
console.log(index+" got maximum time repeated, with "+ max +" times" );
Solo copie y pegue en la consola de Chrome para ejecutar el código anterior.
Probando un enfoque declarativo aquí. Esta solución crea un objeto para contar las ocurrencias de cada palabra. Luego filtra el objeto a una matriz comparando las ocurrencias totales de cada palabra con el valor más alto encontrado en el objeto.
const arr = [''hello'', ''world'', ''hello'', ''again''];
const tally = (acc, x) => {
if (! acc[x]) {
acc[x] = 1;
return acc;
}
acc[x] += 1;
return acc;
};
const totals = arr.reduce(tally, {});
const keys = Object.keys(totals);
const values = keys.map(x => totals[x]);
const results = keys.filter(x => totals[x] === Math.max(...values));
Pruébalo también, esto no tiene en cuenta la versión del navegador.
function mode(arr){
var a = [],b = 0,occurrence;
for(var i = 0; i < arr.length;i++){
if(a[arr[i]] != undefined){
a[arr[i]]++;
}else{
a[arr[i]] = 1;
}
}
for(var key in a){
if(a[key] > b){
b = a[key];
occurrence = key;
}
}
return occurrence;
}
alert(mode([''segunda'',''terça'',''terca'',''segunda'',''terça'',''segunda'']));
Tenga en cuenta que esta función devuelve la última ocurrencia en la matriz cuando aparecen 2 o más entradas la misma cantidad de veces.
Puedes intentar esto:
// using splice()
// get the element with the highest occurence in an array
function mc(a) {
var us = [], l;
// find all the unique elements in the array
a.forEach(function (v) {
if (us.indexOf(v) === -1) {
us.push(v);
}
});
l = us.length;
while (true) {
for (var i = 0; i < l; i ++) {
if (a.indexOf(us[i]) === -1) {
continue;
} else if (a.indexOf(us[i]) != -1 && a.length > 1) {
// just delete it once at a time
a.splice(a.indexOf(us[i]), 1);
} else {
// default to last one
return a[0];
}
}
}
}
// using string.match method
function su(a) {
var s = a.join(),
uelms = [],
r = {},
l,
i,
m;
a.forEach(function (v) {
if (uelms.indexOf(v) === -1) {
uelms.push(v);
}
});
l = uelms.length;
// use match to calculate occurance times
for (i = 0; i < l; i ++) {
r[uelms[i]] = s.match(new RegExp(uelms[i], ''g'')).length;
}
m = uelms[0];
for (var p in r) {
if (r[p] > r[m]) {
m = p;
} else {
continue;
}
}
return m;
}
Se han producido algunos desarrollos en javascript desde 2009; pensé que agregaría otra opción. Estoy menos preocupado con la eficiencia hasta que realmente es un problema, por lo que mi definición de código "elegante" (según lo estipulado por el OP) favorece la legibilidad, lo que por supuesto es subjetivo ...
function mode(arr){
return arr.sort((a,b) =>
arr.filter(v => v===a).length
- arr.filter(v => v===b).length
).pop();
}
mode([''pear'', ''apple'', ''orange'', ''apple'']); // apple
En este ejemplo particular, si dos o más elementos del conjunto tienen ocurrencias iguales, entonces se devolverá el que aparece más reciente en el conjunto. También vale la pena señalar que modificará su matriz original, lo que puede evitarse si lo desea con una llamada Array.slice
antemano.
Editar: actualicé el ejemplo con algunas flechas de grasa de ES6 porque el año 2015 pasó y creo que se ven bonitas ... Si le preocupa la compatibilidad con versiones anteriores, puede encontrar esto en el historial de revisiones .
Según George Jempty''s
solicitud de George Jempty''s
para que el algoritmo tenga en cuenta los vínculos, propongo una versión modificada Matthew Flaschen''s
algoritmo de Matthew Flaschen''s
.
function modeString(array)
{
if (array.length == 0)
return null;
var modeMap = {},
maxEl = array[0],
maxCount = 1;
for(var i = 0; i < array.length; i++)
{
var el = array[i];
if (modeMap[el] == null)
modeMap[el] = 1;
else
modeMap[el]++;
if (modeMap[el] > maxCount)
{
maxEl = el;
maxCount = modeMap[el];
}
else if (modeMap[el] == maxCount)
{
maxEl += ''&'' + el;
maxCount = modeMap[el];
}
}
return maxEl;
}
Esto ahora devolverá una cadena con los elementos de modo delimitados por un símbolo ''&''
. Cuando se recibe el resultado, se puede dividir en ese elemento ''&''
y usted tiene su (s) modo (s).
Otra opción sería devolver una matriz de elemento (s) modo así:
function modeArray(array)
{
if (array.length == 0)
return null;
var modeMap = {},
maxCount = 1,
modes = [];
for(var i = 0; i < array.length; i++)
{
var el = array[i];
if (modeMap[el] == null)
modeMap[el] = 1;
else
modeMap[el]++;
if (modeMap[el] > maxCount)
{
modes = [el];
maxCount = modeMap[el];
}
else if (modeMap[el] == maxCount)
{
modes.push(el);
maxCount = modeMap[el];
}
}
return modes;
}
En el ejemplo anterior, usted podría manejar el resultado de la función como una matriz de modos.
Supongo que tienes dos enfoques. Ambos tienen ventajas.
Clasifique luego Count o Loop through y use una tabla hash para hacer el conteo por usted.
La tabla hash es agradable porque una vez que terminas de procesar, también tienes todos los elementos distintivos. Sin embargo, si tuviera millones de elementos, la tabla hash podría terminar usando mucha memoria si la tasa de duplicación es baja. El enfoque de ordenar, luego contar tendría una huella de memoria mucho más controlable.
Tiempo para otra solución:
function getMaxOccurrence(arr) {
var o = {}, maxCount = 0, maxValue, m;
for (var i=0, iLen=arr.length; i<iLen; i++) {
m = arr[i];
if (!o.hasOwnProperty(m)) {
o[m] = 0;
}
++o[m];
if (o[m] > maxCount) {
maxCount = o[m];
maxValue = m;
}
}
return maxValue;
}
Si la brevedad importa (no es así), entonces:
function getMaxOccurrence(a) {
var o = {}, mC = 0, mV, m;
for (var i=0, iL=a.length; i<iL; i++) {
m = a[i];
o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
if (o[m] > mC) mC = o[m], mV = m;
}
return mV;
}
Si se deben evitar miembros inexistentes (por ejemplo, matriz dispersa), se requiere una prueba hasOwnProperty adicional:
function getMaxOccurrence(a) {
var o = {}, mC = 0, mV, m;
for (var i=0, iL=a.length; i<iL; i++) {
if (a.hasOwnProperty(i)) {
m = a[i];
o.hasOwnProperty(m)? ++o[m] : o[m] = 1;
if (o[m] > mC) mC = o[m], mV = m;
}
}
return mV;
}
getMaxOccurrence([,,,,,1,1]); // 1
Otras respuestas aquí regresarán indefinidas .
a=[''pear'', ''apple'', ''orange'', ''apple''];
b={};
max='''', maxi=0;
for(let k of a) {
if(b[k]) b[k]++; else b[k]=1;
if(maxi < b[k]) { max=k; maxi=b[k] }
}
const mode = (str) => {
return str
.split('' '')
.reduce((data, key) => {
let counter = data.map[key] + 1 || 1
data.map[key] = counter
if (counter > data.counter) {
data.counter = counter
data.mode = key
}
return data
}, {
counter: 0,
mode: null,
map: {}
})
.mode
}
console.log(mode(''the t-rex is the greatest of them all''))
function mode(){
var input = $("input").val().split(",");
var mode = [];
var m = [];
var p = [];
for(var x = 0;x< input.length;x++){
if(m.indexOf(input[x])==-1){
m[m.length]=input[x];
}}
for(var x = 0; x< m.length;x++){
p[x]=0;
for(var y = 0; y<input.length;y++){
if(input[y]==m[x]){
p[x]++;
}}}
for(var x = 0;x< p.length;x++){
if(p[x] ==(Math.max.apply(null, p))){
mode.push(m[x]);
}}
$("#output").text(mode);}
function mode(arr){
return arr.reduce(function(counts,key){
var curCount = (counts[key+''''] || 0) + 1;
counts[key+''''] = curCount;
if (curCount > counts.max) { counts.max = curCount; counts.mode = key; }
return counts;
}, {max:0, mode: null}).mode
}
function mode(array){
var set = Array.from(new Set(array));
var counts = set.map(a=>array.filter(b=>b==a).length);
var indices = counts.map((a,b)=>Math.max(...counts)===a?b:0).filter(b=>b!==0);
var mode = indices.map(a=>set[a]);
return mode;
}
var array = [1, 3, 6, 6, 6, 6, 7, 7, 12, 12, 17],
c = {}, // counters
s = []; // sortable array
for (var i=0; i<array.length; i++) {
c[array[i]] = c[array[i]] || 0; // initialize
c[array[i]]++;
} // count occurrences
for (var key in c) {
s.push([key, c[key]])
} // build sortable array from counters
s.sort(function(a, b) {return b[1]-a[1];});
var firstMode = s[0][0];
console.log(firstMode);
var mode = 0;
var c = 0;
var num = new Array();
var value = 0;
var greatest = 0;
var ct = 0;
Nota: ct es la longitud de la matriz.
function getMode()
{
for (var i = 0; i < ct; i++)
{
value = num[i];
if (i != ct)
{
while (value == num[i + 1])
{
c = c + 1;
i = i + 1;
}
}
if (c > greatest)
{
greatest = c;
mode = value;
}
c = 0;
}
}