
Casi todos los problemas que enfrentamos los desarrolladores todos los días se pueden resolver como un conjunto de problemas mas pequeños: soluciones pequeñas para problemas individuales bien definidos. Estas soluciones se pueden describir mejor como funciones puras.
Aunque la mayoría de estas funciones se implementan en diferentes librerías, es importante comprender cómo y cuándo dividir los problemas difíciles en otros más pequeños. Esta forma de pensar sobre la resolución de problemas aumentará su productividad y lo convertirá en un mejor desarrollador.
A continuación les voy a compartir una colección de 15 funciones puras útiles que uso regularmente para resolver todo tipo de problemas.
15 funciones puras útiles
Get value
Dado un objeto o un arreglo, la función devolverá el valor en la ruta especificada; de lo contrario, devolverá null.
const getValue = (obj, path) => path
.replace(/\[([^[\]]*)]/g, '.$1.')
.split('.')
.filter(prop => prop !== '')
.reduce((prev, next) => (
prev instanceof Object ? prev[next] : undefined
), obj);
getValue({ a: { b: { c: 'd' } } }, 'a.b.c'); // = d
getValue({ a: { b: { c: [1, 2] } } }, 'a.b.c[1]'); // = 2
Clamp
Asegura que un valor se encuentre dentro de un rango específico; de lo contrario, retorna el valor más cercano entre el valor mínimo y máximo.
const clamp = (min, max, value) => {
if (min > max) throw new Error('min cannot be greater than max');
return value < min
? min
: value > max
? max
: value;
}
clamp(0, 10, -5); // = 0
clamp(0, 10, 20); // = 10
Sleep
Espera la duración especificada en milisegundos antes de realizar la siguiente operación.
const sleep = async (duration) => (
new Promise(resolve =>
setTimeout(resolve, duration)
)
);
await sleep(1000); // espera 1 seg
Group by
Agrupa e indexa elementos relacionados en un objeto de acuerdo con la keying-function.
const groupBy = (fn, list) => (
list.reduce((prev, next) => ({
...prev,
[fn(next)]: [...(prev[fn(next)] || []), next]
}), {})
);
groupBy(vehicle => vehicle.make, [
{ make: 'tesla', model: '3' },
{ make: 'tesla', model: 'y' },
{ make: 'ford', model: 'mach-e' },
]);
// {
// tesla: [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
// ford: [ { make: 'ford', ... } ],
// }
Collect By
Crea sublistas que contengan elementos relacionados de acuerdo con la keying-function.
import groupBy from './groupBy';
const collectBy = (fn, list) =>
Object.values(groupBy(fn, list));
collectBy(vehicle => vehicle.make, [
{ make: 'tesla', model: '3' },
{ make: 'tesla', model: 'y' },
{ make: 'ford', model: 'mach-e' },
]);
// [
// [ { make: 'tesla', ... }, { make: 'tesla', ... } ],
// [ { make: 'ford', ... } ],
// ]
Head
Obtiene el primer elemento de una lista. Esta función es útil para escribir código limpio y legible.
const head = list => list[0];
head([1, 2, 3]); // = 1
head([]); // = undefined
Tail
Obtener todos menos el primer elemento de una lista. Esta función es útil para escribir código limpio y legible.
const tail = list => list.slice(1);
tail([1, 2, 3]); // = [2, 3]
tail([]); // = []
Flatten
Cree una flat list extrayendo todos los elementos de las sublistas anidadas de forma recursiva.
const flatten = list => list.reduce((prev, next) => ([
...prev,
...(Array.isArray(next) ? flatten(next) : [next])
]), []);
flatten([[1, 2, [3, 4], 5, [6, [7, 8]]]]); // = [1, 2, 3, 4, 5, 6, 7, 8]
Index By
Indexe cada elemento en una lista por un valor determinado por la keying-function.
const indexBy = (fn, list) =>
list.reduce((prev, next) => ({
...prev,
[fn(next)]: next
}), {});
indexBy(val => val.a, [{ a: 1 }, { a: 2 }, { a: 3 }]);
// = { 1: { a: 1 }, 2: { a:2 }, 3: { a: 3 } }
Difference By
Encuentre todos los elementos en la primera lista que no están presentes en la segunda lista, determinados por la keying-function.
import indexBy from './indexBy';
const differenceBy = (fn, listA, listB) => {
const bIndex = indexBy(fn, listb);
return listA.filter(val => !bIndex[fn(val)]);
});
differenceBy(val => val, [1,2,3], [3,4,5]); // = [1,2]
differenceBy(
vehicle => vehicle.make,
[{ make: 'tesla' }, { make: 'ford' }, { make: 'gm' }],
[{ make: 'tesla' }, { make: 'bmw' }, { make: 'audi' }],
); // = [{ make: 'ford' }, { make: 'gm' }]
Sum By
Calcular la suma de todos los elementos de una lista dada alguna función que produzca el valor individual de cada elemento.
const sumBy = (fn, list) =>
list.reduce((prev, next) => prev + fn(next), 0);
sumBy(product => product.price, [
{ name: 'pizza', price: 10 },
{ name: 'pepsi', price: 5 },
{ name: 'salad', price: 5 },
]); // = 20
Ascending
Crea una función de comparación ascendente dada una función.
const ascending = (fn) => (a, b) => {
const valA = fn(a);
const valB = fn(b);
return valA < valB ? -1 : valA > valB ? 1 : 0;
}
const byPrice = ascending(val => val.price);
[{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
// = [{ price: 100 }, { price: 200 }, { price: 300 }]
Descending
Crea una función de comparación descendente dada una función.
const descending = (fn) => (a, b) => {
const valA = fn(b);
const valB = fn(a);
return valA < valB ? -1 : valA > valB ? 1 : 0;
}
const byPrice = descending(val => val.price);
[{ price: 300 }, { price: 100 }, { price: 200 }].sort(byPrice);
// = [{ price: 300 }, { price: 200 }, { price: 100 }]
Find Key
Encuentra la primera key dentro de un índice que satisfaga el predicado dado.
const findKey = (predicate, index) => Object
.keys(index)
.find(key => predicate(index[key], key, index));
findKey(
car => !car.available,
{
tesla: { available: true },
ford: { available: false },
gm: { available: true }
},
); // = "ford"
Bifurcate By
Divide los valores de una lista dada en dos listas, una que contenga los valores que la función de predicado evalúa como verdaderos y la otra lista que contenga los falsos.
const bifurcateBy = (predicate, list) =>
list.reduce((acc, val, i) => (
acc[predicate(val, i) ? 0 : 1].push(val), acc),
[[], []]
);
bifurcateBy(val => val > 0, [-1, 2, -3, 4]);
// = [[2, 4], [-1, -3]]
Aunque todas estas funciones pueden ser realmente útiles para ayudarlo a resolver los problemas en los que está trabajando, la lección más importante es saber cómo dividir problemas complejos y difíciles en pequeños problemas bien definidos que se pueden resolver de forma independiente. Una vez que domines esto, ¡ya estarás en camino de convertirte en un excelente desarrollador!
Contenido del articulo
- Comentarios
Comentarios
No hay comentarios. Inicia sesión para comentar.