Estoy tratando de ensuciarme la mano con Javascript
Quiero resolver el siguiente ejercicio (que se encuentra en Codewars):
Dada una matriz de números enteros, encuentre el que aparece un número impar de veces.
Siempre habrá un solo número entero que aparecerá un número impar de veces.
[7] debería devolver 7, porque ocurre 1 vez (lo cual es impar). [0] debería devolver 0, porque ocurre 1 vez (lo cual es impar). [1,1,2] debería devolver 2, porque ocurre 1 vez (lo cual es impar). [0,1,0,1,0] debería devolver 0, porque ocurre 3 veces (lo cual es impar). [1,2,2,3,3,3,4,3,3,3,2,2,1] debería devolver 4, porque aparece 1 vez (lo cual es impar).
este es mi código:
function findOdd(A) { const isOdd = (x) => { return x%2; } const counts ={}; for ( i of A) { counts[i]= counts[i] ? counts[i] +1:1; } const numOccurences = (Object.values(counts)); const occurences = Object.getOwnPropertyNames(counts); let evenOccurence=0; let oddOccurence; for (let y=0;y<numOccurences.length;y++) { if(isOdd(numOccurences[y])) { console.log("numOccurences[y] is equal to: ",numOccurences[y]) evenOccurence = numOccurences[y]; console.log(`value ${occurences[y]} is appearing ${numOccurences} times which is even`) } // } // console.log("evenOccurence",evenOccurence); // return evenOccurence; } return evenOccurence; } // console.log(findOdd([7])); console.log(findOdd([7,7,8,8,7,5,5,5,5,5,5,5]));mi problema es el valor que estoy poniendo en evenOccurrence, esperaría un número entero, pero viene como 7,3,2 en la matriz dada como ejemplo.
¿alguien podría ayudarme por favor?
Gracias por adelantado
Podría tomar un XOR ^ bit a bit que elimina incluso los valores de conteo.
const odd = array => array.reduce((a, b) => a ^ b, 0); console.log(odd([1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1])); console.log(odd([7])); console.log(odd([1, 1, 2])); Otro enfoque. Con un objeto para mantener el estado. El valor es true o false según la apariencia extraña del valor de la matriz.
Finalmente tome todas las llaves y encuentre la que tenga el valor true .
const odd = array => { const states = {}; for (const value of array) states[value] = !states[value]; return +Object.keys(states).find(k => states[k]); }; console.log(odd([1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1])); console.log(odd([7])); console.log(odd([1, 1, 2]));Actualiza tu respuesta con un comentario.
function findOdd(A) { const isOdd = (x) => { return x % 2; } const counts = {}; // key with will be unique set of A and value will be part will be occurence count for (i of A) { counts[i] = counts[i] ? counts[i] + 1 : 1; } // const numOccurences = (Object.values(counts)); // her you are just getting list of how many time they occured, without any reference to A or their keys // const occurences = Object.getOwnPropertyNames(counts); let evenOccurence = []; // if you want to return a list, create a list and push values in it for (let key of Object.keys(counts)) { // key is unique value of A let occurenceCount = counts[key]; if (isOdd(occurenceCount)) { console.log("numOccurences of key [", key,"] is equal to: ", occurenceCount, ' odd') } else { console.log("numOccurences of key [", key,"] is equal to: ", occurenceCount, ' event') evenOccurence.push(key); } } return evenOccurence; } console.log(findOdd([7, 7, 8, 8, 7, 5, 5, 5, 5, 5, 5, 5]));El primer algoritmo de @Nina Scholz es una obra maestra. Básicamente, es muy simple si está de acuerdo con las operaciones bit a bit. Solo me gustaría simplificar lo mismo a las matemáticas diarias.
var odd = array => array.sort().reduce((a,b,i) => i%2 ? ab : a+b); console.log(odd([1, 2, 2, 3, 3, 3, 4, 3, 3, 3, 2, 2, 1])); console.log(odd([7])); console.log(odd([1, 1, 2]));