4

Me gustaria saber porque pasa lo siguiente... Haciendo una funcion que toma el valor del medio de tres numeros probe con la primera idea que me vino a la mente es la funcion que esta aqui abajo..

    function valorMedio (inputArray) {
        console.log(`arreglo original: [${inputArray}]`);
        let mid = inputArray.sort((a,b) => a-b)[1]
        console.log(`arreglo final: [${inputArray}]`);
        return inputArray.indexOf(mid)
    };

    console.log(valorMedio([15, 22, -7]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

es sencilla; ordeno el arreglo tomo el segundo numero del arreglo ordenado y lo asigno a una variable y luego busco el indice de este numero en el arreglo original. El problema es que el arreglo muta me regresa indice 1 cuando deberia ser el indice 0, independientemente si lo que estoy haciendo es tomando un valor de mi arreglo original este ordenado.. Cosa que si hago ej: mid =inputArray.sort((a,b) => a-b).join('') y toda la complicacion de luego no sucede.. Normalmente si quiero cambiar un arreglo que recibo por parametro hago inputArray = inputArray.sort((a,b) => a-b) array = array.modificaciones().

function valorMedio (inputArray) {
    console.log(`arreglo original: [${inputArray}]`);
    let mid = [...inputArray].sort((a,b)=>a-b)[1]
    
    console.log(`arreglo final: [${inputArray}]`);
    return inputArray.indexOf(mid)
};

console.log(valorMedio([15, 22, -7]));
console.log(valorMedio([1, -22, 75]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

pense que no era extraño estaba asignando una referencia.. y resolvi haciendo copia del arreglo esta funcion de arriba pero lo raro fue que si hago:

function valorMedio2(a) {
    return a.indexOf(a.sort((a, b) => a - b )[1])
}


function valorMedio3(a) {
    return a.indexOf(a.concat().sort((a, b) => a - b )[1])
}

console.log('Incorrecto '+valorMedio2([15, 22, -7]));
console.log('Correcto '+valorMedio3([15, 22, -7]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

CON EL concat() SOLUCIONO EL PROBLEMA... Que es lo que pasa en Javascript que muta el arreglo???

Pablo Lozano
  • 45,934
  • 7
  • 48
  • 87
RazerJs
  • 2,253
  • 2
  • 10
  • 36

1 Answers1

3

El método sort muta el array y lo devuelve. Por tanto, da igual que intentes guardar el resultado de la ordenación en una nueva variable o no, puesto que seguirás trabajando con el array original:

const a = [3,5,2,1,4];

const b = a.sort((a,b)=> a-b);

console.log(a.toString(), a === b); //a y b son la misma instancia

Por otro lado, el método concat crea un nuevo array, así que en cada función estás pidiendo que busque por índice en dos arrays distintos. Para que veas la diferencia he reescrito tus funciones haciendo cada paso más explícito:

function valorMedio2(a) {
    return a.indexOf(a.sort((a, b) => a - b )[1])
}


function valorMedio3(a) {
    return a.indexOf(a.concat().sort((a, b) => a - b )[1])
}

function valorMedio2Expandida(a) {
    a.sort((a, b) => a - b );
    const elementoMedio = a[1];
    return a.indexOf(elementoMedio); //tiene que ser 1!
}


function valorMedio3Expandida(a) {
    const copiaDeA= a.concat();
    copiaDeA.sort((a, b) => a - b );
    const elementoMedio = copiaDeA[1];
    return a.indexOf(elementoMedio); //devuelve la posición original
}

console.log(valorMedio3Expandida([1,3,2])); //el dos está en la posición 2
Pablo Lozano
  • 45,934
  • 7
  • 48
  • 87
  • @Pablo_Lozano otra cosa es que aunque asigne el valor a una constante ej: `const medio=a.sort((a, b) => a - b )[1]` tmb muta q segun lo que entiendo de const eso no deberia pasar... si hago un slice() al arreglo tampoco me pasa como con el concat – RazerJs Oct 07 '19 at 15:09
  • 1
    @IsraelGonzález Te recomiendo leer [cómo funcionan las constantes en JS](https://es.stackoverflow.com/questions/106042/var-let-const-o-nada-en-javascript/106067#106067) – Pablo Lozano Oct 07 '19 at 15:12
  • Gracias! Pablo Lozano – RazerJs Oct 07 '19 at 15:27
  • @PabloLozano con respecto al uso de `===` con arrays habría que aclarar que compara la referencia, `[] === []` o `[1,2,3] === [1,2,3]` da `false`. Lo que está diciendo esa comparación es que se trata del mismo array. No se puede comparar así si dos arrays contienen los mismos valores. – Emeeus Oct 07 '19 at 22:41
  • @Emeeus Lo añadiré, tienes razón: no queda claro – Pablo Lozano Oct 08 '19 at 07:17
  • Hola Pablo, si pudieras añadir [el enlace de MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/sort) a `Array.prototype.sort`, sería bueno para futuros lectores. Así podrían notar que al inicio aclara _El método sort() ordena los elementos de un array localmente (...)_ – ElChiniNet Oct 08 '19 at 08:59
  • Pablo no es mejor poner en el titulo Javascript o esto puede suceder en otros lenguajes? – RazerJs Oct 08 '19 at 09:21
  • Para buscar preguntas relacionadas con Javascript, escribe `[javascript]` en el campo de búsqueda. Lo que pongas entre corchetes son [etiquetas y no deben añadirse en el título](https://es.stackoverflow.com/help/tagging) . – Pablo Lozano Oct 08 '19 at 09:23