This is a minimalistic library aimed to reuse logic on HashTables mapping, that i use over and over i.e. consuming API results to pass to Twig views.
Makes easy to do filtering/renaming of unwanted keys through simple dictionary of keys of source to target. Through callbacks supports any transformation, and passing it another callable or another instance of HashMapper, pretty complex transformation of associative arrays, a.k.a as Hashmaps for friends.
use function Apantle\HashMapper\hashMapper;
$target = hashMapper($specs, $options)($source);
You can install the package via composer:
composer require apantle/hashmapper
Change one key in input, only output that in target.
Input | Mapper | Output |
---|---|---|
['origin' => 'Africa']; |
hashMapper(['origin' => 'roots]) |
['roots' => 'Africa'] |
For somewhat complex transforms, you can use a function that will receive as arguments:
- the value of the source hashmap specified at key:
- the whole hashmap if you need other values of it
assert(hashMapper([
'place' => 'Caso CIDH',
'date' => [
'fecha',
function($date, $source) {
extract($date);
$date = date_create_from_format('Y/m/d', "{$year}/{$month}/{$day}");
return $date->format('Y-m-d');
}
],
])([
'date' => [
'year' => 2006,
'month' => 5,
'day' => 4,
],
'place' => 'San Salvador Atenco',
]) === [
'Caso CIDH' => 'San Salvador Atenco',
'fecha' => '2006-05-04'
]);
If you have a complex subkey that is not easily mapped with a simple function, you could use another HashMapper with the spec for that subkey, as the mapper for that key.
assert(hashMapper([
'sourceKey' => hashMapper([ 'value' => 'legend' ])
])([
'sourceKey' => [
'value' => 'to pass to HashMapper',
'ignored' => 'it should not appear'
],
]) === [
'sourceKey => [
'legend' => 'to pass to HashMapper'
]
]);
If you want to take a key with subkeys of the source and spread it (copy
the dictionary of key and values it contains) on the target hashmap, you
can pass a tuple with the string '...'
as the target key, and your chosen callable.
assert(hashMapper([
'wp:term' => ['...', 'Apantle\FunPHP\identity']
])([
'wp:term' => [
'id' => 31925,
'link' => 'http://example.com/category/test-term/',
'name' => 'Test term',
'slug' => 'test-term',
'taxonomy' => 'category',
],
'ignored' => 'right'
]) === [
'id' => 31925,
'link' => 'http://example.com/category/test-term/',
'name' => 'Test term',
'slug' => 'test-term',
'taxonomy' => 'category',
]);
If you need all the dictionaries inside top level keys be spread into the
target, rather than writing your mapping spec as a tuple, you can give it
only a callable, specifying the option implicitSpread => true
in the
constructor to the Mapper functor.
assert(hashMaper(
[
'wp:term' => compose('Apantle\FunPHP\head', 'Apantle\FunPHP\identity'),
],
[
'implicitSpread' => true
]
)([
'wp:term' => [
[
'id' => 31925,
'link' => 'http://example.com/category/test-term/',
'name' => 'Test term',
'slug' => 'test-term',
'taxonomy' => 'category',
]
],
]) === [
'id' => 31925,
'link' => 'http://example.com/category/test-term/',
'name' => 'Test term',
'slug' => 'test-term',
'taxonomy' => 'category',
]);
For better reuse, now offers through the __invoke
magic, a simpler way to use
it to map a collection of associative arrays, as array_map
, array_reduce
or
Collection::map
(from Illuminate\Support
).
Instead of using the HashMapper as the function for array_map
or Collection::map
,
you can use our own helper, that applies the same set of transformations
to every array passed.
$collectionTransformed = collection(hashMapper($specs))($arrayOfAssociativeArrays);
See issue:1 for more complete examples in test sources.