Comparar elemento actual con el anterior: limitaciones de SCAN y solución elegante

Un miembro de la comunidad intenta usar SCAN con una "matriz coja" (dos columnas apiladas horizontalmente) para comparar cada elemento con el anterior y contar los cambios. Pero SCAN siempre compara el mismo elemento consigo mismo, no con el anterior.

Nacho explica por qué falla: SCAN solo procesa la primera columna de su array de entrada. Aunque le pases una matriz de dos columnas con APILARH, SCAN ignora la segunda.

La fórmula original que no funcionaba:

``
=LET(
ra_1; A1:A11;
ra_2; A2:A12;
arr; APILARH(ra_1; ra_2);
result; SCAN(1; arr; LAMBDA(a; row;
UNIRCADENAS("-"; VERDADERO; INDICE(row; 0); INDICE(row; 1))
));
ELEGIRCOLS(result; 1)
)
`

Alternativa con MAP (Argentina): para trabajar con dos rangos en paralelo, MAP acepta múltiples arrays como entrada:

`
=MAP(A1:A11; A2:A12; LAMBDA(prev; curr; prev&"-"&curr))
`

La solución definitiva (John): el problema real no era concatenar, sino contar cambios entre elementos consecutivos. Para eso, no hace falta ni MAP ni LAMBDA:

`
=SCAN(1; A1:A11 <> A2:A12; SUMA)
`

A1:A11 <> A2:A12 genera un array booleano (VERDADERO donde hay cambio), y SCAN con SUMA` acumula el conteo. Elegante y sin una sola función LAMBDA.

Comparar cada valor de una columna con el anterior es una de esas tareas que parecen triviales hasta que intentas hacerlas sin columnas auxiliares. Un miembro de la comunidad quería contar cuántas veces cambia el valor a lo largo de una lista, y lo intentó con SCAN pasándole una "matriz coja": dos columnas apiladas, la original y la misma desplazada una fila. El resultado no era el esperado, y la explicación deja una lección muy útil sobre cómo funciona realmente SCAN.

Por qué falla el intento con SCAN

La fórmula de partida era esta:

=LET(
    ra_1; A1:A11;
    ra_2; A2:A12;
    arr; APILARH(ra_1; ra_2);
    result; SCAN(1; arr; LAMBDA(a; row;
        UNIRCADENAS("-"; VERDADERO; INDICE(row; 0); INDICE(row; 1))
    ));
    ELEGIRCOLS(result; 1)
)

La idea era buena: si apilo el rango consigo mismo desplazado, cada fila tiene a la vez el valor actual y el anterior. El problema es que SCAN solo procesa la primera columna del array que le pasas. Aunque montes una matriz de dos columnas con APILARH, la segunda se ignora por completo. Por eso la fórmula acaba comparando cada elemento consigo mismo en vez de con su vecino.

Merece la pena grabárselo: SCAN está pensado para recorrer un vector arrastrando un acumulador, no para recorrer filas de una matriz de varias columnas.

Alternativa con MAP: dos rangos en paralelo

Si de verdad necesitas trabajar con dos rangos a la vez, la función correcta es MAP, que acepta varios arrays de entrada y los recorre en paralelo, posición a posición:

=MAP(A1:A11; A2:A12; LAMBDA(prev; curr; prev&"-"&curr))

Aquí prev recibe el elemento del primer rango y curr el del segundo. Como el segundo rango arranca una fila más abajo, cada pareja que llega a la LAMBDA es exactamente "valor anterior y valor actual". Esta es la forma canónica de comparar elementos consecutivos en Excel 365.

La solución definitiva: ni MAP ni LAMBDA

John dio con el planteamiento que resuelve el problema original de raíz. El objetivo nunca fue concatenar textos, sino contar los cambios entre elementos consecutivos. Y para eso no hace falta ninguna función lambda:

=SCAN(1; NO(A1:A11 = A2:A12); SUMA)

Lo que ocurre paso a paso:

  1. A1:A11 = A2:A12 compara cada elemento con el siguiente y devuelve una matriz de VERDADERO cuando son iguales.
  2. NO(...) le da la vuelta: ahora hay un VERDADERO justo en cada posición donde el valor cambia.
  3. SCAN con SUMA acumula esa matriz de booleanos, así que el resultado es el conteo de cambios acumulado a lo largo de la lista.

Fíjate en el detalle elegante: SUMA se pasa como función, sin envolverla en LAMBDA. Es la llamada eta-lambda, y funciona siempre que la función que quieres aplicar ya acepte los argumentos en el orden correcto. La fórmula queda en una línea y sin una sola declaración de variables.

Cuándo usar cada uno

  • SCAN: un solo vector, y necesitas arrastrar un estado (acumulados, rellenos, contadores). Recuerda que ignora la segunda columna en adelante.
  • MAP: varios rangos que hay que recorrer a la vez, elemento contra elemento. Es la herramienta natural para "actual contra anterior".
  • Aritmética booleana directa: cuando lo único que quieres es contar o marcar coincidencias, muchas veces no necesitas ni MAP ni LAMBDA. Una comparación entre dos rangos desplazados ya produce toda la información.

Funciones clave

  • SCAN: acumula sobre un vector y devuelve todos los resultados intermedios.
  • MAP: aplica una LAMBDA a varios arrays en paralelo.
  • NO: invierte una matriz de valores lógicos; sirve para expresar "distinto de" sin operadores raros.
  • APILARH y ELEGIRCOLS: útiles para montar y recortar matrices, aunque en este caso el problema se resolvió sin ellas.

Conclusión

El caso deja dos aprendizajes que valen para muchísimas fórmulas: primero, que SCAN mira solo la primera columna, y segundo —más importante— que antes de complicar la fórmula conviene volver a la pregunta original. Aquí la duda parecía "cómo concateno el elemento anterior con el actual" y en realidad era "cuántos cambios hay". Con la pregunta bien planteada, la respuesta cabía en una línea.

Estos giros pasan a diario en la comunidad de InflueXcel: alguien trae una fórmula que no funciona y acaba saliendo una versión más corta y más rápida que la original.

Más casos con estas funciones

Más contenido de Excel en InflueXcel