hand Inicio

Reduce para implementar pipping

Por pipping() se entiende una manera de concatenar métodos que nos permite ser más declarativos y programar más funcionalmente (huyendo de la orientación a objetos)

Utilizando reduce para piping

El reduce no deja de ser un superMap, un superForEach o un superFilter (aquí tienes la entrada donde te lo explico)

Pero qué pasa cuando utilizamos el reduce para iterar un conjunto de funciones?

Pues que podemos implementar el pipping

Ejemplo: qué pasa si queremos aplicar a una cadena de texto un tratamiento concreto

js
// funciones genéricas
const sanitize = str => str.replace(/[^a-zA-Z ]/g, '')
const addParagraph = str => '<p>' + str + '</p>'
const addTitle = str => '<h1>MY VERY SPECIAL TITLE</h1>' + str

// el texto que recibiría de un formulario
const data = 'this is my fantastic text that here and there and blah with <a href="">a forbidden link!!</a>'

const prepare = [sanitize, addParagraph, addTitle]

// mi resultado final (opción 1)
const opcion1_1 = sanitize(data)
const opcion1_2 = addParagraph(opcion1_1)
const opcion1_3 = addTitle(opcion1_2)

console.log(opcion1_1) // this is my fantastic text that here and there and blah with a hrefa forbidden linka
console.log(opcion1_2) // <p>this is my fantastic text that here and there and blah with a hrefa forbidden linka</p>
console.log(opcion1_3) // <h1>MY VERY SPECIAL TITLE</h1><p>this is my fantastic text that here and there and blah with a hrefa forbidden linka</p>

// mi resultado final (opción 2)
const opcion2 = addTitle(addParagraph(sanitize(data)))

console.log(opcion2) // <h1>MY VERY SPECIAL TITLE</h1><p>this is my fantastic text that here and there and blah with a hrefa forbidden linka</p>

La opción 1 es algo desastre, y la opción 2 es simplemente el infierno

Siempre podríamos utilizar una variable let pero claro, estaríamos mutando esa variable y esto va en contra de los principios de la programación funcional (porque si algo muta, nos puede traer problemas en el futuro, y más en React donde las cosas van rerenderizándose cada dos por tres)

La solución?

Utilizar reduce

js
// funciones genéricas
const sanitize = str => str.replace(/[^a-zA-Z ]/g, '')
const addParagraph = str => '<p>' + str + '</p>'
const addTitle = str => '<h1>MY VERY SPECIAL TITLE</h1>' + str

// el texto que recibiría de un formulario
const data = 'this is my fantastic text that here and there and blah with <a href="">a forbidden link!!</a>'

// funciones que quiero aplicar en un orden específico
const prepare = [sanitize, addParagraph, addTitle]

// el texto después de aplicarle mi tratamiento
const myFinalString = prepare.reduce((final, metodo) => metodo(final), data)

console.log(myFinalString)
// <h1>MY VERY SPECIAL TITLE</h1><p>this is my fantastic text that here and there and blah with a hrefa forbidden linka</p>

Super elegante, y a esto se le llama hacer una pipe (una tubería)

Pero sin duda cada vez que aparece la palabra reduce tenemos que hacer un esfuerzo para leer y entender lo que hace esa función

La solución?

Redefinir la función anterior en una función que llamaremos pipe

js
// función pipe
const pipe = fs => x => fs.reduce((v, f) => f(v), x);

// funciones genéricas
const sanitize = str => str.replace(/[^a-zA-Z ]/g, '')
const addParagraph = str => '<p>' + str + '</p>'
const addTitle = str => '<h1>MY VERY SPECIAL TITLE</h1>' + str

// el texto que recibiría de un formulario
const data = 'this is my fantastic text that here and there and blah with <a href="">a forbidden link!!</a>'

// funciones que quiero aplicar en un orden específico
const prepare = [sanitize, addParagraph, addTitle]

// el texto después de aplicarle mi tratamiento
const myFinalString = pipe(prepare)(data)

console.log(myFinalString)
// <h1>MY VERY SPECIAL TITLE</h1><p>this is my fantastic text that here and there and blah with a hrefa forbidden linka</p>

Tenemos lo mismo, pero de una forma mucho más legible

Más información, en

🙋‍♂️

draw of me

Hola, tienes en mente desarrollar una web?

Si quieres, te ayudo

Escríbeme