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