Skip to content

Commit

Permalink
feat/add-support-for-map (#9)
Browse files Browse the repository at this point in the history
* Add map support for `DataModelHelper.php`,

* Update `README.md`.

---------

Co-authored-by: david_smith <[email protected]>
  • Loading branch information
zero-to-prod and david_smith authored Oct 29, 2024
1 parent a26e254 commit f6afa9f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 9 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class User
'coerce' => true, // Coerce single elements into an array
'using' => [self::class, 'map'], // Custom mapping function
'map_via' => 'mapper', // Custom mapping method (defaults to 'map')
'map' => [self::class, 'keyBy'], // Run a function for that value.
'level' => 1, // The dimension of the array. Defaults to 1.
'key_by' => 'key', // Key an associative array by a field.
])]
Expand Down Expand Up @@ -330,6 +331,8 @@ echo $User->Aliases[0][1]->name; // Outputs: John Smith
Key an array by an element value by using the `key_by` argument.

This also supports deep mapping.

Note: this only applies to arrays.
```php
class User
{
Expand Down Expand Up @@ -368,4 +371,48 @@ $User = User::from([

echo $User->Aliases['jd1']->name; // 'John Doe'
echo $User->Aliases['js1']->name); // 'John Smith'
```

#### Map
Call a function for that value.

Note: This does not work with arrays.
```php
class User
{
use \Zerotoprod\DataModel\DataModel;
use \Zerotoprod\DataModelHelper\DataModelHelper;

/** @var Alias[] $Aliases */
#[Describe([
'cast' => [self::class, 'mapOf'],
'type' => Alias::class,
'map' => [self::class, 'keyBy'],
])]
public Collection $Aliases;

public static function keyBy(Collection $values): Collection
{
return $values->keyBy('id');
}
}

class Alias
{
use \Zerotoprod\DataModel\DataModel;

public string $id;
public string $name;
}

$User = User::from([
'Aliases' => [
[
'id' => 'jd1',
'name' => 'John Doe',
]
]
]);

echo $User->Aliases->get('jd1')->name; // 'John Doe'
```
20 changes: 11 additions & 9 deletions src/DataModelHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,21 +60,23 @@ public static function mapOf(mixed $value, array $context, ?ReflectionAttribute
$method = $args[0]['method'] ?? 'from';
$type = $Property->getType()?->getName();
$map = $args[0]['map_via'] ?? 'map';
$classname = $args[0]['type'];
$keyBy = static fn($value, ?string $key_by) => $key_by && count(array_column($value, $key_by))
? array_combine(array_column($value, $key_by), $value)
: $value;

$mapper = static function ($value, $level = 1) use ($keyBy, $args, $classname, $map, $type, $method, &$mapper) {
$mapper = static function ($value, $level = 1) use ($args, $map, $type, $method, &$mapper) {
return $type === 'array'
? array_map(static fn($item) => $level <= 1
? $classname::$method($item)
? $args[0]['type']::$method($item)
: $mapper($item, $level - 1),
$keyBy($value, $args[0]['key_by'] ?? null))
: (new $type($keyBy($value, $args[0]['key_by'] ?? null)))
($args[0]['key_by'] ?? null) && count(array_column($value, ($args[0]['key_by'] ?? null)))
? array_combine(array_column($value, ($args[0]['key_by'] ?? null)), $value)
: $value)
: (new $type(
is_callable($args[0]['map'] ?? null)
? $args[0]['map']($value)
: $value
))
->$map(
fn($item) => $level <= 1
? $classname::$method($item)
? $args[0]['type']::$method($item)
: $mapper($item, $level - 1)
);
};
Expand Down

0 comments on commit f6afa9f

Please sign in to comment.