Php - Clase array wrapper que permite hacer queries sobre un array y aplicar map, filter y reduce encadenados

Wrapper para potenciar transformaciones sobre un array en php

Acostumbrado ha trabajar con los métodos filter, map y reduce que tiene JS se me hacía un poco extraño sus equivalentes en php. Por otro lado recurría constantemente a cierta lógica similar a las consultas que se hacen en SQL.
Por ejemplo me llegaba un json, lo transformaba en array y seguidamente me tocaba limpiar información irrelevante equivalente a aplicar un WHERE, después tenía que quedarme con n columnas algo parecido a SELECT y en casos más complejos hacer intersecciones entre dos arrays JOINS.

Para estas operaciones creé esta clase, la llamé Arrayquery. Actúa como un helper que permite transformar un array inicial o simplemente hacer queries sobre este.
La clase no tiene dependencias de otros paquetes o clases por lo tanto si no te interesa el nombre o le namespace copia y pega su contenido en una nueva.

El código fuente lo puedes encontrar aquí

El archivo con las pruebas aquí

Arrayquery ejemplos

use TheFramework\Components\ComponentArrayquery; //supongamos que un endpoint me devuelve esto $ar1 = [ ["id"=>1,"description"=>"some description 1 x","price"=>10.00,"date"=>"20100220"], ["id"=>2,"description"=>"some description 2 y","price"=>20.22,"date"=>"20221001"], ["id"=>3,"description"=>"some description 3 z","price"=>20.22,"date"=>"20221001"], ["id"=>4,"description"=>"some description 1 x","price"=>10.00,"date"=>"20100220"], ["id"=>5,"description"=>"some description 2 y","price"=>20.22,"date"=>"20221001"], ["id"=>6,"description"=>"some description 3 z","price"=>20.22,"date"=>"20221001"], ["id"=>7,"description"=>"some description 6 z","price"=>20.25,"date"=>"20221105"], ["id"=>8,"description"=>"some description 8 v","price"=>5.99,"date"=>"20170228"], ["id"=>9,"description"=>null,"price"=>7.65,"date"=>"20100228"], ["id"=>10,"description"=>"","price"=>13.99,"date"=>"19900228"], ]; //otra llamada me devuelve lo siguiente $ar2 = [ ["id"=>1,"description"=>"some description 1 a","price"=>10.00,"date"=>"20100220"], ["id"=>2,"description"=>"some description 2 y","price"=>20.22,"date"=>"20221001"], ["id"=>3,"description"=>"some description 3 z","price"=>20.22,"date"=>"20221001"], ["id"=>4,"description"=>"some description 1 x","price"=>10.00,"date"=>"20100220"], ["id"=>5,"description"=>"some description 2 c","price"=>20.22,"date"=>"20221001"], ["id"=>6,"description"=>"some description 3 z","price"=>20.22,"date"=>"20221001"], ["id"=>7,"description"=>"some description 6 z","price"=>20.25,"date"=>"20221105"], ["id"=>8,"description"=>"some description 8 v","price"=>5.99,"date"=>"20170228"], ["id"=>9,"description"=>null,"price"=>7.65,"date"=>"20100228"], ["id"=>11,"description"=>"","price"=>13.99,"date"=>"19900228"], ];

Ejemplo 1 map, filter reduce

$oComp = new ComponentArrayquery($ar1); //probando map, filter reduce $r = $oComp->map(function($item){ return [ //transformo el array original, cambio date por day y price por p "id" => $item["id"], "name"=> $item["description"], "day"=>$item["date"], "p"=>$item["price"] ]; }) ->filter(function ($item){ //me quedo con los precios > 10 return $item["p"] > 10; }) ->reduce(function($ac, $item){ //sumo los precios return $ac + $item["p"]; },0) ->get_result() ; //resultado: 115.11999999999999

Ejemplo 2 distinct y where

$oComp = new ComponentArrayquery($ar1); $r = $oComp->remove_column(["id"])->distinct()->where("price",20.22)->get_result(); /** array ( 0 => array ( 'description' => 'some description 2 y', 'price' => 20.22, 'date' => '20221001', ), 1 => array ( 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', ), ) */ $r = $oComp->distinct()->where("price","20.2%","like")->where("date","%05","like" )->get_result(); /* array ( 0 => array ( 'id' => 7, 'description' => 'some description 6 z', 'price' => 20.25, 'date' => '20221105', ), ) */ $r = $oComp->distinct()->where("description","%z%","like")->get_result(); /* array ( 0 => array ( 'id' => 3, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', ), 1 => array ( 'id' => 6, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', ), 2 => array ( 'id' => 7, 'description' => 'some description 6 z', 'price' => 20.25, 'date' => '20221105', ), ) */ //otras opciones: $r = $oComp->distinct()->where("price",6,">")->where("price",11,"<")->get_result(); $r = $oComp->is_null("description")->get_result(); $r = $oComp->is_empty("description")->get_result(); $r = $oComp->in("date", ["20221001","20221105"])->not_in("description", ["some description 2 y"])->get_result();

Ejemplo join y order by

$r = $oComp->innerjoin($ar2,["id"=>"id","description"=>"description"])->orderby("date", "desc")->get_result(); /* array ( 0 => array ( 'id' => 7, 'description' => 'some description 6 z', 'price' => 20.25, 'date' => '20221105', ), 1 => array ( 'id' => 3, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', ), 2 => array ( 'id' => 6, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', ), ) */ $r = $oComp->leftjoin($ar2,["id"=>"id","description"=>"description"])->orderby("date", "desc")->get_result(); /* array ( 0 => array ( 'id' => 7, 'description' => 'some description 6 z', 'price' => 20.25, 'date' => '20221105', '*leftjoin*' => 0, ), 1 => array ( 'id' => 3, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', '*leftjoin*' => 0, ), 2 => array ( 'id' => 6, 'description' => 'some description 3 z', 'price' => 20.22, 'date' => '20221001', '*leftjoin*' => 0, ), ) */

Autor: Eduardo A. F.
Publicado: 30-12-2020 22:08