Skip to content

Instantly share code, notes, and snippets.

@maemichi-monosense
Last active December 26, 2018 03:21
Show Gist options
  • Save maemichi-monosense/e4589680ef10323f7ade0bbd665e3b76 to your computer and use it in GitHub Desktop.
Save maemichi-monosense/e4589680ef10323f7ade0bbd665e3b76 to your computer and use it in GitHub Desktop.
PHP utils
<?php
namespace ArrayUtils;
/**
* deep get
*
* @param array $array
* @param string|int ...$keys
*
* @return array|mixed
*/
function dig(array $array, ...$keys)
{
foreach ($keys as $key) {
$array = $array[$key];
}
return $array;
}
/**
* deep set
*
* @param array $array
* @param mixed $value
* @param string|int ...$keys
*
* @return bool set or not
*/
function bury(array &$array, $value, ...$keys): bool
{
if (empty($keys)) {
return false;
}
$last = array_pop($keys);
foreach ($keys as $key) {
$array =& $array[$key];
}
$array[$last] = $value;
return true;
}
/**
* split an array into 2 arrays
*
* @param array $array
* @param int $index
*
* @return array[] [array, array]
*/
function splitAt(array $array, int $index): array
{
$first = array_slice($array, 0, $index);
$last = array_slice($array, $index);
return [$first, $last];
}
<?php
require 'array_utils.php';
use function \ArrayUtils\dig, \ArrayUtils\bury;
$a0 = [0, [1, 2]];
assert(2 === dig($a0, 1, 1));
$set = bury($a0, 'foo', 1, 0);
assert($set);
assert('foo' === dig($a0, 1, 0));
<?php
namespace IterUtils;
/**
* @param int $start
* @param int $limit
* @param int $step
*
* @return \Generator
*/
function xrange(int $start, int $limit, int $step = 1): \Generator
{
for ($i = $start; $i <= $limit; $i += $step) {
yield $i;
}
}
function take(int $n, \Iterator $iterator): \Generator
{
while($n > 0 && $iterator->valid()) {
yield $iterator->current();
$iterator->next();
--$n;
}
}
/**
* @see http://blog.kevingomez.fr/2016/02/26/efficiently-creating-data-chunks-in-php/
*
* @param \Iterator $iterable
* @param int $size
*
* @return \Generator
*/
function chunk(\Iterator $iterable, int $size): \Generator
{
if (!($size > 0)) {
throw new \InvalidArgumentException('Size must be positive');
}
while ($iterable->valid()) {
yield take($size, $iterable);
}
}
<?php
require 'iter_utils.php';
use function \IterUtils\xrange;
use function \IterUtils\chunk;
$expected = [
[
[0, 0, 0],
[0, 1, 1],
[0, 2, 2],
],
[
[1, 0, 3],
[1, 1, 4],
[1, 2, 5],
],
[
[2, 0, 6],
[2, 1, 7],
[2, 2, 8],
],
];
$iters = chunk(xrange(0, 8), 3);
$actual = [];
foreach ($iters as $i => $iter) {
$ns = [];
foreach ($iter as $j => $n) {
$ns []= [$i, $j, $n];
}
$actual []= $ns;
}
assert($expected === $actual);
@maemichi-monosense
Copy link
Author

TODO

  • zip iter
  • refactor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment