Skip to content

Instantly share code, notes, and snippets.

@zanbaldwin
Last active May 15, 2021 09:35
Show Gist options
  • Save zanbaldwin/f4fee5c7229c2b64844a813140fe45d1 to your computer and use it in GitHub Desktop.
Save zanbaldwin/f4fee5c7229c2b64844a813140fe45d1 to your computer and use it in GitHub Desktop.
<?php declare(strict_types=1);
if (!\function_exists('array_map_recursive')) {
function array_map_recursive(array $array, callable $function): array
{
$out = [];
foreach ($array as $key => $value) {
$out[$key] = \is_array($value)
? array_map_recursive($value, $function)
: \call_user_func($function, $value, $key);
}
return $out;
}
}
<?php declare(strict_types=1);
/**
* @see http://raganwald.com/2018/08/30/to-grok-a-mockingbird.html
*/
function memoize(\Closure $function): \Closure
{
static $lookup = [];
return function (...$args) use ($function, &$lookup) {
$key = \sha1(\json_encode(\array_map_recursive($args, function ($value) {
return \is_object($value) ? \spl_object_hash($value) : $value;
})));
return $lookup[$key] ?? ($lookup[$key] = $function(...$args));
};
}
function mockingbird(\Closure $function): callable
{
return function (...$args) use ($function) {
return $function($function, ...$args);
};
}
$exponent = function (\Closure $self, int $x, int $n): int {
if ($n === 0) {
return 1;
} elseif ($n % 2 === 1) {
return $x * $self($self, $x * $x, (int) \floor($n / 2));
} else {
return $self($self, $x * $x, $n / 2);
}
};
$exp = mockingbird(memoize($exponent));
echo $exp(2, 8) . \PHP_EOL;
echo $exp(2, 8) . \PHP_EOL;
echo $exp(2, 9) . \PHP_EOL;
echo \PHP_EOL;
<?php declare(strict_types=1);
if (!\function_exists('unflatten')) {
/**
* Takes a flat array (such as from an SQL result set) and unflattens it according to dot-notation, such as:
* ['username' => 'admin', 'metadata.created' => '2018-04-24', 'metadata.updated' => '2018-09-17']
*
* [
* 'username' => 'admin',
* 'metadata' => [
* 'created' => '2018-04-24',
* 'updated' => '2018-09-17',
* ],
* ]
*/
function unflatten(array $array): array
{
$out = [];
foreach ($array as $dotNotation => $value) {
if (!\is_string($dotNotation)) {
$out[$dotNotation] = $value;
continue;
}
$keys = explode('.', $dotNotation);
while ($key = \array_pop($keys)) {
$value = [$key => $value];
}
$out = \array_merge_recursive($out, $value);
}
return $out;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment