-
Notifications
You must be signed in to change notification settings - Fork 11.3k
[12.x] Add append keys with arr helper #55565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 12.x
Are you sure you want to change the base?
Conversation
Why not use |
I think Laravel is a lot about expressive code and also a bit about syntactic sugar: The |
Maybe adding a Then we can deprecate the |
@ldommer @AndrewMast Yeah, I don't feel, this was an ideal addition either. There should be something more along the lines of (pseudo code, mind you) enum ArrayEntryTuplePart {
case Key;
case Value;
case Both;
}
enum ArrayEntryTransformType {
case Prepend;
case Append;
case Replace;
}
class Arr
{
// …
static public function map(
array $array,
callable $callback,
ArrayEntryTuplePart $part = ArrayEntryTuplePart::Value,
ArrayEntryTransformType $type = ArrayEntryTransformType::Replace
): array {
$transform = fn (string|int $old, string|int $new) => match ($type) {
ArrayEntryTransformType::Prepend => $new.$old,
ArrayEntryTransformType::Append => $old.$new,
ArrayEntryTransformType::Replace => $new,
};
$mapKey = function (array $array, string|int $key, callable $callback) {
$result = $callback($array[$key], $key);
$value = reset($result);
return [ key($result), $value ];
};
return match ($part) {
ArrayEntryTuplePart::Key => array_reduce(array_keys($array), fn (array $carry, $key) => [ ...$carry, $transform($key, $callback($key)) => $array[$key] ], []),
ArrayEntryTuplePart::Value => array_map($callback, $array),
default => array_reduce(array_keys($array), fn (array $carry, $key) => [ ...$carry, ($transform($key, ([ $newKey, $newValue ] = $mapKey($array, $key, $callback))[0])) => $newValue ], []),
};
}
// …
} This, of course, then could get wrappers that would have pre-configured values for the flags. More examples static public function mapKeys(array $array, callable $callback, ArrayEntryTransformType $type = ArrayEntryTransformType::Replace)
{
return self::map($array, $callback, ArrayEntryTuplePart::Key, $type);
}
static public function prependKeysWith(array $array, string|int $prefix)
{
return self::map($array, fn () => $prefix, ArrayEntryTuplePart::Key, ArrayEntryTransformType::Prepend);
}
static public function appendKeysWith(array $array, string|int $suffix)
{
return self::map($array, fn () => $suffix, ArrayEntryTuplePart::Key, ArrayEntryTransformType::Append);
}
/**
* @param int-mask-of<MB_CASE_*> $case
* @see [`mb_convert_case()`](https://www.php.net/manual/en/function.mb-convert-case.php)
*/
static public function transformKeyCase(array $array, int $case)
{
return self::map($array, fn ($key) => mb_convert_case($key, $case), ArrayEntryTuplePart::Key);
}
static public function pregMap(array $array, string|array $pattern, string|array $replacement, ArrayEntryTuplePart $part = ArrayEntryTuplePart::Value)
{
return self::map($array, fn ($entry) => preg_replace($pattern, $replacement, $entry), $part);
}
@rodrigopedra This, because of the aforementioned point, goes more in the direction I imagined 👍🏻 |
I like @rodrigopedra's idea of a /**
* Transform the key names of an associative array.
*
* @template TKey
* @template TValue
* @template TTransformedKey of array-key
*
* @param array<TKey, TValue> $array
* @param callable(TKey): TTransformedKey $callback
* @return array<TTransformedKey, TValue>
*/
public static function transformKeys(array $array, callable $transformer)
{
return static::mapWithKeys($array, fn ($item, $key) => [$transformer($key) => $item]);
} Then the methods could be like this: /**
* Prepend the key names of an associative array.
*
* @param array $array
* @param string $prependWith
* @return array
*/
public static function prependKeysWith($array, $prependWith)
{
return static::transformKeys($array, fn ($key) => $prependWith.$key);
} /**
* Append the key names of an associative array.
*
* @param array $array
* @param string $appendWith
* @return array
*/
public static function appendKeysWith($array, $appendWith)
{
return static::transformKeys($array, fn ($key) => $key.$appendWith);
} |
@AndrewMast I updated my reply with examples. These also include @rodrigopedra's |
@shaedrich I feel like your method adds a level of unneeded complexity that will be run for every This is my logic:
|
A normal
Sorry if I gave that impression. Removing it never has been my intention. Adding your method, at least, is a reasonable follow-up as we already have the complementary method and won't remove it, at least in the near future.
I hope, that has the wanted effect. Keep in mind that the class is already
I used default parameters to both prevent BC problems as well as allowing for users not to case about them as long as they want to just map or use a wrapper helper like shown in my additional hypothetical examples |
@shaedrich Saying we shouldn't remove the @ldommer I think this PR is a pretty good idea. I suggest you add a test for the method. Take a look at the current test for |
I can totally see the point of @shaedrich of not bloating the But I really like the argumentation and solution of @AndrewMast and couldn't have written it better 👍. I think it makes totally sense to have the two probably most used key transformations as expressive predefined methods and I also really like the idea of @rodrigopedra of having a flexible transformer for all kinds of string operations on array keys, because a) this solution could catch every still so rare edge case someone wants to execute and b) it resembles Laravels callback approach. @AndrewMast Thank you for the hint of adding a test. I didn't find the |
Non-breaking change that adds the missing
appendKeysWith
method to theArr
helper class.This can be useful for mass-updating the keys of API response data or preparing validation rule arrays that are reused, but under different keys having suffixes.
The docs PR can be found here: laravel/docs#10352