w3schools - tipos de funciones en javascript
¿Puedo hacer que esta función sea aún más corta? (2)
Estoy intentando avanzar más hacia la programación funcional en mis aplicaciones de JavaScript. Actualmente uso la biblioteca ramda como una base de lib para esto.
Mi deseo:
- Cree una función
findWithId(id, list)
que devuelva el elemento en la lista con la propiedad_id
coincida con el ID de entrada. - Haga que la implementación sea lo más breve posible, confiando en el código existente tanto como sea posible.
Acheived hasta ahora:
Mi base es R.find
que tiene esta defensa find :: (a -> Boolean) -> [a] -> a | undefined
find :: (a -> Boolean) -> [a] -> a | undefined
Probé algunas soluciones diferentes que se muestran a continuación:
//Using ramdajs (ramdajs.com)
var hasId = R.curry(function(id, item) {
return item._id === id
});
//This doesn''t work
var findWithId_v1 = R.find(hasId);
//This works but can I make it as short as v1?
var findWithId_v2 = function(id, list) {
return R.find(hasId(id), list);
}
Pregunta
¿Puedo hacer que findWithId_v2
tan corto como findWithId_v1
usando herramientas de programación funcional estándar como componer, curry, etc.?
Demo de Plunker
Está buscando la función de compose
:
compose :: (a -> b) -> (b -> c) -> (a -> c)
hasId :: p -> (i -> Boolean)
find :: (i -> Boolean) -> ([i] -> i | undefined)
compose :: (p -> (i -> Boolean))
-> ((i -> Boolean) -> ([i] -> i | undefined))
-> (p -> ([i] -> i | undefined))
compose find hasId :: p -> ([i] -> i | undefined)
Entonces harías
var findWithId = R.compose(R.find, hasId)
Ah, y note que no necesita una expresión de función para hasId
:
var hasId = R.propEq(''_id'');
Ramda tiene una función que ayudará con esto, una llamada useWith
. Si puedes pensar en un nombre mejor, me encantaría. Ya lo he preguntado antes .
Puedes usar es así:
var findById = R.useWith(R.find, hasId, R.identity);
var find5 = findById(5);
find5([{id:3}, {id:5}]); //=> {id:5}
findById(5, [{id:3}, {id:5}]); //=> {id:5}
No tiene que proporcionar R.identity
arriba. Esto también funcionaría, aunque prefiero ser explícito:
var findById = R.useWith(R.find, hasId);
useWith "acepta una función fn
y cualquier número de funciones de transformador y devuelve una nueva función. Cuando se invoca la nueva función, llama a la función fn
con parámetros que consisten en llamar a cada controlador suministrado en sucesivos argumentos a la nueva función"