apantle / hashmapper Goto Github PK
View Code? Open in Web Editor NEWMinimalistic utility to apply mapping rules to associative arrays in PHP (hashmap for friends)
Minimalistic utility to apply mapping rules to associative arrays in PHP (hashmap for friends)
Pasar las opciones con que se puede configurar la función se implementa mediante un array associativo de opciones, lo que no facilita recibir ayuda del IDE para implementar rápidamente la opción requerida.
Las alternativas con una serie de constantes de clase que sean pasadas como segundo argumento y funciones como una serie de bits independientes entre sí, como funcionan actualmente las opciones, o bien un objeto que implemente una interfaz que devuelva las opciones de configuración.
Para ampliar un poco el alcance de la aplicabilidad de esta librería, podemos proporcionar simplemente un par de opciones a cada hashMapper, que funcionen como filtros de entrada, y así pudiendo implementar fácilmente algoritmos más complejos como transformar y validar un objeto mediante un simple helper, y sanitizar la salida como excluir claves con informes de error que sería deseable loggear en un servicio externo pero no devolver al usuario final en el frontend, por poner un ejemplo.
Esto puede ser conseguido con relativa facilidad mediante un par de opciones para el hashMapper, sería útil para otros casos, poder obtener un collectionMapper con filtros para toda la colección, distintos a los que se aplicarían a cada elemento de la colección recibida.
Los ejemplos dados son más bien simples para facilitar la comprensión de la plataforma, sin embargo al ser utilizados en otros proyectos pueden mostrar mejor su utilidad.
El patrón en que operar una key puede ser pasado a otro hashMapper (decorador), es muy útil, pero recientemente se hace más pertinente aplicar una serie de hashMapper en patrón pipeline, permitiéndoles a cada uno operar una transformación distinta, haciendo efectivamente posible expresar algoritmos cada vez más complejos solo mediante la trasformación de arrays associativos.
Actualmente implementar un algoritmo así es muy sencillo combinando una serie de hashMapper con un pipe de apantle/fun-php#4
$results = pipe(
hashMapper($transformsSpec, $options),
hashMapper($transformsSpec, $options),
hashMapper($transformsSpec, $options)
)( $inputArray );
Sin embargo si requerimos que no cada hashMapper filtre toda la entrada, sino digamos, agregue o aplique funciones al array de entrada, especificar en cada $options se vuelve repetitivo y se pierde la intención de las transformaciones entre boilerplate:
// ...
hashMapper($validateQueriesSpec, ['passThroughNoMatched' => true]),
hashMapper($resolveQueriesSpec, ['passThroughNoMatched' => true]),
hashMapper($captureAndFilterErrors. ['passThroughNoMatched' => true])
A pesar de poder resumir las opciones en una variable en este caso, rápidamente vuelve a explotar la complejidad al requerir, por ejemplo, que algunos mappers tengan unas opciones distintas.
Pero además apuntamos siempre a que esta librería facilite patrones funcionales donde la intención del programador al escribir las transformaciones a una colección de datos de entrada, no quede oscurecida en un mar de sintaxis, además de que la lógica de las funciones sea fácil de componer y mantener.
Así pues, poder especificar con una utilidad de esta misma librería, una serie de transformaciones a aplicar a un array de entrada, con el mínimo ruido extra posible, podría plantear un consumo así:
hashMapperPipe(
$validateQueriesSpecArray,
$resolveQueriesSpecArray,
$captureAndFilterErrors,
[ $logStatistics, $logOptions ]
$commonOptions
)
Para facilitar su uso en una comunidad más amplia, la documentación en español sería de gran ayuda pues al final somos la segunda lengua más hablada del mundo, pero tenemos muy poca documentación en nuestra lengua nativa.
Algunas funciones de uso simple como strval
arrojan errores al pasarles además del dato a mapear, el hashmap siendo iterado. Por lo que hace falta algo de Reflection para poder ubicar dicho caso y evitarnos funciones adaptadores.
Convendrá una opción o parámetro o helper adicional para hacer del hashmap devuelto un objeto?
Leer de un objeto como si fuese un hashMap?
También, valdría la pena hacer de la Collection un Iterable? Ya sea un objeto Collection (como el de Illuminate), o solo una lista de objetos de determinado tipo?
Debido a que la verificación de que una función mapper es unary introducido en #7, se realiza con Reflection, como salvaguarda para próximas optimizaciones, como dar soporte a callables en objetos (actualmente solo soporta funciones como cadena), deberíamos introducir una prueba y corregir si no pasa, de que la verificación de función unary solo se llama una única vez por instancia (y no por cada invocación cuando se reusa el hashmapper varias veces).
Relacionado con #1 , una función para obtener el collection Mapper desde un hashMapper ya creado puede facilitar aún más su uso en pipes, pienso en algo como:
collection(hashMapper($rules))
La mayoría de la documentación está hecha en un momento en que esta librería se facilitaba solo mediante un objeto mapper a inicializar con los spec en el constructor. Sin embargo ahora se promueve más su uso como una función de filtro, que internamente construye un objeto HashmapMapperInterface
. Asimismo el propio objeto se exporta como un Functor que permite pasarle directamente el array a mapear.
Así, en aras de facilitar documentar más casos de uso (#2) y el uso del collectionMapper (#1), cambiaré el formato de la documentación a tablas que muestren más claramente la entrada, salida y qué mapper produce dicha transformación, así como preferir crear el objeto Mapper con las funciones facilitadas en lugar de la construcción de objetos manualmente.
Compose, identity, constant, Pipe y otros deberían publicarse como paquete aparte.
La clase que provee este paquete, proporciona un método para obtener un CollectionMapper, con el que se pueden aplicar los mapeos configurados para un solo array asociativo, a un array de array asociativo con la misma estructura.
Ver las pruebas en:
hashmapper/tests/ImplicitPassNotMatchedOptionsMapperTest.php
Lines 112 to 116 in ad74922
hashmapper/tests/FunctionsTest.php
Lines 48 to 71 in ad74922
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.