PHP code example of krak / fn

1. Go to this page and download the library: Download krak/fn library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

krak / fn example snippets




use function Krak\Fun\Curried\{filter, map, op};
use function Krak\Fun\{compose};
use const Krak\Fun\Consts\{toArray};

$res = compose(
    toArray,
    map(op('*')(3)),
    filter(op('>')(2))
)([1,2,3,4]);
assert($res == [9, 12]);



use Krak\Fun\{f, c};

$res = f\compose(
    c\toArray,
    c\map(c\op('*')(3)),
    c\filter(c\op('>')(2))
)([1,2,3,4]);
assert($res == [9, 12]);

use Krak\Fun\{f, c};

$res = f\compose(
    c\toArray,
    c\map(function($tup) {
        return $tup[0] + $tup[1];
    }),
    c\toPairs
)([1,2,3]);
// $res == [1, 3, 5]



use Krak\Fun\{f, c};

function getArrayRange(callable $toArray): array {
    $toArray(f\range(1,3));
}

getArrayRange(c\toArray);

use Krak\Fun\{f, c};

$res = f\compose(
    c\toArray,
    map(partial(c\op, '*', 3))
)([1,2,3]);
assert($res == [3,6,9]);

func()
func($arg1)
func($oarg = null, $oarg1 = null)

func($arg1, $arg2)
func($arg1, $oarg = null)

    f\compose(
        function() {}, // do something else
        c\dd(), // debug result here
        function() {}, // do another thing that returns a single value
        function() {} // do something
    );
    

    f\compose(
        function() {}, // do something else
        c\dd(), c\toArray, // debug result here
        c\map(function() {}) // do something
    );
    


use Krak\Fun\{f, c};

/**
 * Fetches orders based off of the arguments, filters data, and imports to database
 */
final class ImportOrdersFromApi
{
    public function __construct(ApiClient $client, OrderRepository $orderRepository, SaveOrders $saveOrders) {
        // ...
    }

    public function __invoke(ImportOrderRequest $req): void {
        f\compose(
            $this->persistApiOrders(),
            $this->removeAlreadyImportedOrders(),
            $this->fetchOrdersFromApi()
        )($req);
    }

    private function persistApiOrders(): callable {
        // important that this is an c\each so that it will consume the iterable chain
        return f\compose(
            c\each($this->saveOrders), // saveOrders has a signature of `__invoke(iterable Order[]) => void`
            c\chunk(50), // chunk to persist many at once
            c\map(function(array $apiOrder) {
                return Order::createFromApiData($apiOrder);
            })
        );
    }

    private function removeAlreadyImportedOrders(): callable {
        return f\compose(
            c\flatMap(function(array $apiOrders) {
                $apiOrderIds = array_column($apiOrders, 'order_id');
                /** array of order id => order entity */
                $orders = $this->orderRepository->findByApiOrderIds($ids);
                return f\filter(function(array $apiOrder) use ($orders) {
                    return !array_key_exists($apiOrder['order_id'], $orders);
                }, $apiOrders);
            }),
            // chunk by 50 to save on database requests
            c\chunk(50)
        );
    }

    /** Returns an iterable of api orders */
    private function fetchOrdersFromApi(): callable {
        return function(ImportOrderRequest $req) {
            yield from $this->apiClient->fetch(/* pass in req args */);
        };
    }
}

$res = all(function ($v) {
    return $v % 2 == 0;
}, [2, 4, 6]);
expect($res)->equal(true);

$res = all(function ($v) {
    return $v % 2 == 0;
}, [1, 2, 4, 6]);
expect($res)->equal(false);

$res = any(function ($v) {
    return $v % 2 == 0;
}, [1, 3, 4, 5]);
expect($res)->equal(true);

$res = any(function ($v) {
    return $v % 2 == 0;
}, [1, 3, 5]);
expect($res)->equal(false);

$res = arrayCompact([1, 2, null, null, 3]);
expect(\array_values($res))->equal([1, 2, 3]);

$res = arrayFilter(partial(op, '<', 2), [1, 2, 3]);
expect($res)->equal([1]);

$res = arrayFilter(partial(op, '<', 2), range(1, 3));
expect($res)->equal([1]);

$res = arrayMap(partial(op, '*', 2), [1, 2, 3]);
expect($res)->equal([2, 4, 6]);

$res = arrayMap(partial(op, '*', 2), range(1, 3));
expect($res)->equal([2, 4, 6]);

$res = arrayReindex(function ($v) {
    return $v['id'];
}, [['id' => 2], ['id' => 3], ['id' => 1]]);
expect($res)->equal([2 => ['id' => 2], 3 => ['id' => 3], 1 => ['id' => 1]]);

$results = arrayMap(arrayWrap, [1, 'abc', ['a' => 1]]);
expect($results)->equal([[1], ['abc'], [['a' => 1]]]);

$results = arrayMap(arrayWrap, [[], [1, 2, 3]]);
expect($results)->equal([[], [1, 2, 3]]);

$obj = new \StdClass();
$obj = assign($obj, ['a' => 1, 'b' => 2]);
expect($obj->a)->equal(1);
expect($obj->b)->equal(2);

$res = chain([1], range(2, 3));
expect(toArray($res))->equal([1, 2, 3]);

$res = chunk(2, [1, 2, 3, 4]);
expect(toArray($res))->equal([[1, 2], [3, 4]]);

$res = chunk(3, [1, 2, 3, 4]);
expect(toArray($res))->equal([[1, 2, 3], [4]]);

$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$chunks = chunkBy(function (string $item) {
    return $item[0];
    // return first char
}, $items);
expect(toArray($chunks))->equal([['aa', 'ab', 'ac'], ['ba', 'bb', 'bc'], ['ca', 'cb', 'cc']]);

$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$chunks = chunkBy(function (string $item) {
    return $item[0];
    // return first char
}, $items, 2);
expect(toArray($chunks))->equal([['aa', 'ab'], ['ac'], ['ba', 'bb'], ['bc'], ['ca', 'cb'], ['cc']]);

$res = compact([1, null, 2, 3, null, null, 4]);
expect(toArray($res))->equal([1, 2, 3, 4]);

$mul2 = Curried\op('*')(2);
$add3 = Curried\op('+')(3);
$add3ThenMul2 = compose($mul2, $add3);
$res = $add3ThenMul2(5);
expect($res)->equal(16);

$res = compose(Curried\reduce(function ($acc, $v) {
    return $acc + $v;
}, 0), function () {
    yield from [1, 2, 3];
})();
expect($res)->equal(6);

$res = construct(\ArrayObject::class, [1, 2, 3]);
expect($res->count())->equal(3);

$res = curry(_idArgs::class, 2)(1)(2)(3);
expect($res)->equal([1, 2, 3]);

$res = differenceWith(partial(op, '==='), [1, 2, 3, 4, 5], [2, 3, 4]);
expect(toArray($res))->equal([1, 5]);

$res = null;
$died = false;
$dump = function ($v) use(&$res) {
    $res = $v;
};
$die = function () use(&$died) {
    $died = true;
};
dd(1, $dump, $die);
expect($res)->equal(1);
expect($died)->equal(true);

$res = drop(2, range(0, 3));
expect(toArray($res))->equal([2, 3]);

$res = dropWhile(Curried\op('>')(0), [2, 1, 0, 1, 2]);
expect(toArray($res))->equal([0, 1, 2]);

$state = [(object) ['id' => 1], (object) ['id' => 2]];
each(function ($item) {
    $item->id += 1;
}, $state);
expect([$state[0]->id, $state[1]->id])->equal([2, 3]);

$values = filter(partial(op, '>', 2), [1, 2, 3, 4]);
// keep all items that are greater than 2
expect(toArray($values))->equal([3, 4]);

$res = filterKeys(Curried\inArray(['a', 'b']), ['a' => 1, 'b' => 2, 'c' => 3]);
expect(toArrayWithKeys($res))->equal(['a' => 1, 'b' => 2]);

$res = flatMap(function ($v) {
    return [-$v, $v];
}, range(1, 3));
expect(toArray($res))->equal([-1, 1, -2, 2, -3, 3]);

$res = flatten([1, [2, [3, [4]]]]);
expect(toArray($res))->equal([1, 2, 3, 4]);

$res = flatten([1, [2, [3]]], 1);
expect(toArray($res))->equal([1, 2, [3]]);

$res = flatten([1, [2]], 0);
expect(toArray($res))->equal([1, [2]]);

$res = flip(['a' => 0, 'b' => 1]);
expect(toArray($res))->equal(['a', 'b']);

$res = fromPairs([['a', 1], ['b', 2]]);
expect(toArrayWithKeys($res))->equal(['a' => 1, 'b' => 2]);

$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$groupedItems = groupBy(function (string $item) {
    return $item[0];
    // return first char
}, $items);
expect(toArray($groupedItems))->equal([['aa', 'ab', 'ac'], ['ba', 'bb', 'bc'], ['ca', 'cb', 'cc']]);

$items = ['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc'];
$groupedItems = groupBy(function (string $item) {
    return $item[0];
    // return first char
}, $items, 2);
expect(toArray($groupedItems))->equal([['aa', 'ab'], ['ac'], ['ba', 'bb'], ['bc'], ['ca', 'cb'], ['cc']]);

$res = hasIndexIn(['a', 'b', 'c'], ['a' => ['b' => ['c' => null]]]);
expect($res)->equal(true);

$res = hasIndexIn(['a', 'b', 'c'], ['a' => ['b' => []]]);
expect($res)->equal(false);

$res = head([1, 2, 3]);
expect($res)->equal(1);

$res = head([]);
expect($res)->equal(null);

$res = inArray([1, 2, 3], 2);
expect($res)->equal(true);

$res = index('a', ['a' => 1]);
expect($res)->equal(1);

$res = index('a', ['b' => 1], 2);
expect($res)->equal(2);

class MyClass implements \ArrayAccess
{
    private $container = [];
    public function __construct()
    {
        $this->container = ['one' => 1, 'two' => 2];
    }
    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }
    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }
    public function offsetSet($offset, $value)
    {
        /* ... */
    }
    public function offsetUnset($offset)
    {
        /* ... */
    }
}
$object = new MyClass();
expect(index('two', $object))->equal(2);
expect(index('three', $object, 'else'))->equal('else');

$res = indexIn(['a', 'b'], ['a' => ['b' => 1]]);
expect($res)->equal(1);

$res = indexIn(['a', 'b'], ['a' => ['c' => 1]], 2);
expect($res)->equal(2);

$res = indexOf(partial(op, '==', 'b'), ['a', 'b', 'c']);
expect($res)->equal(1);

expect(isNull(null))->equal(true);
expect(isNull(0))->equal(false);

expect(iter([1, 2, 3]))->instanceof('Iterator');

expect(iter(new \ArrayIterator([1, 2, 3])))->instanceof('Iterator');

$obj = (object) ['a' => 1, 'b' => 2];
expect(iter($obj))->instanceof('Iterator');
expect(toArrayWithKeys(iter($obj)))->equal(['a' => 1, 'b' => 2]);

$a = new class implements \IteratorAggregate
{
    public function getIterator()
    {
        return new \ArrayIterator([1, 2, 3]);
    }
};
expect(iter($a))->instanceof('Iterator');
expect(toArray(iter($a)))->equal([1, 2, 3]);

expect(iter('abc'))->instanceof('Iterator');
expect(toArray(iter('abc')))->equal(['a', 'b', 'c']);

expect(function () {
    iter(1);
})->throw('LogicException', 'Iter could not be converted into an iterable.');

$res = join(",", range(1, 3));
expect($res)->equal("1,2,3");

$keys = keys(['a' => 1, 'b' => 2]);
expect(toArray($keys))->equal(['a', 'b']);

$values = map(partial(op, '*', 2), [1, 2, 3, 4]);
expect(toArray($values))->equal([2, 4, 6, 8]);

$data = iter('abcd');
[$totalSort, $values] = mapAccum(function ($acc, $value) {
    return [$acc + 1, ['name' => $value, 'sort' => $acc]];
}, iter('abcd'), 0);
expect($totalSort)->equal(4);
expect($values)->equal([['name' => 'a', 'sort' => 0], ['name' => 'b', 'sort' => 1], ['name' => 'c', 'sort' => 2], ['name' => 'd', 'sort' => 3]]);

$keys = mapKeys(partial(op, '.', '_'), ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($keys))->equal(['a_' => 1, 'b_' => 2]);

$keys = mapKeyValue(function ($kv) {
    [$key, $value] = $kv;
    return ["{$key}_", $value * $value];
}, ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($keys))->equal(['a_' => 1, 'b_' => 4]);

$values = mapOn(['a' => partial(op, '*', 3), 'b' => partial(op, '+', 1)], ['a' => 1, 'b' => 2, 'c' => 3]);
expect(toArray($values))->equal([3, 3, 3]);

expect(nullable('intval', '0'))->equal(0);

expect(nullable('intval', null))->equal(null);

$state = [(object) ['id' => 1], (object) ['id' => 2]];
onEach(function ($item) {
    $item->id += 1;
}, $state);
expect([$state[0]->id, $state[1]->id])->equal([2, 3]);

$res = op('<', 2, 1);
expect($res)->equal(true);

$obj = new stdClass();
$ops = [['==', [1, 1]], ['eq', [2, 2]], ['!=', [1, 2]], ['neq', [2, 3]], ['===', [$obj, $obj]], ['!==', [new stdClass(), new stdClass()]], ['>', [1, 2]], ['gt', [1, 3]], ['>=', [1, 2]], ['gte', [1, 1]], ['<', [2, 1]], ['lt', [3, 1]], ['<=', [2, 1]], ['lte', [1, 1]]];
foreach ($ops as list($op, list($b, $a))) {
    $res = op($op, $b, $a);
    expect($res)->equal(true);
}

$ops = [['+', [2, 3], 5], ['-', [2, 3], 1], ['*', [2, 3], 6], ['**', [2, 3], 9], ['/', [2, 3], 1.5], ['%', [2, 3], 1], ['.', ['b', 'a'], 'ab']];
foreach ($ops as list($op, list($b, $a), $expected)) {
    $res = op($op, $b, $a);
    expect($res)->equal($expected);
}

$add2 = Curried\op('+')(2);
$mul3 = partial(op, '*', 3);
$sub4 = Curried\op('-')(4);
// ((2 + 2) * 3) - 4
$res = compose($sub4, $mul3, $add2)(2);
expect($res)->equal(8);

$res = pad(5, [1, 2, 3]);
expect(toArray($res))->equal([1, 2, 3, null, null]);

$res = pad(5, [1, 2, 3], 0);
expect(toArray($res))->equal([1, 2, 3, 0, 0]);

$res = pad(5, [1, 2, 3, 4, 5]);
expect(toArray($res))->equal([1, 2, 3, 4, 5]);

$res = pad(5, [1, 2, 3, 4, 5, 6]);
expect(toArray($res))->equal([1, 2, 3, 4, 5, 6]);

$res = pad(3, ['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($res))->equal([1, 2, null]);

$fn = function ($a, $b, $c) {
    return ($a + $b) * $c;
};
$fn = partial($fn, 1, 2);
// apply the two arguments (a, b) and return a new function with signature (c) -> d
expect($fn(3))->equal(9);

$fn = function ($a, $b, $c) {
    return ($a + $b) * $c;
};
// _() represents a placeholder for parameter b.
$fn = partial($fn, 1, _(), 3);
// create the new func with signature (b) -> d
expect($fn(2))->equal(9);

$fn = function ($a, $b) {
    return [$a, $b];
};
$fn = partial($fn, 1, 2);
expect($fn())->equal([1, 2]);

list($left, $right) = partition(function ($v) {
    return $v < 3 ? 0 : 1;
}, [1, 2, 3, 4]);
expect([$left, $right])->equal([[1, 2], [3, 4]]);

$res = pick(['a', 'b'], ['a' => 1, 'b' => 2, 'c' => 3]);
expect($res)->equal(['a' => 1, 'b' => 2]);

$res = arrayMap(Curried\pick(['id', 'name']), [['id' => 1, 'name' => 'Foo', 'slug' => 'foo'], ['id' => 2, 'name' => 'Bar', 'slug' => 'bar']]);
expect($res)->equal([['id' => 1, 'name' => 'Foo'], ['id' => 2, 'name' => 'Bar']]);

$res = pickBy(Curried\spread(function (string $key, int $value) : bool {
    return $value % 2 === 0;
}), ['a' => 1, 'b' => 2, 'c' => 3]);
expect($res)->equal(['b' => 2]);

$add3 = Curried\op('+')(3);
$mul2 = Curried\op('*')(2);
$add3ThenMul2 = pipe($add3, $mul2);
$res = $add3ThenMul2(5);
expect($res)->equal(16);

$res = pipe(function () {
    yield from [1, 2, 3];
}, Curried\reduce(function ($acc, $v) {
    return $acc + $v;
}, 0))();
expect($res)->equal(6);

$res = product([1, 2], [3, 4], [5, 6]);
expect(toArray($res))->equal([[1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]]);

$obj = new \StdClass();
$obj->id = 1;
$res = prop('id', $obj);
expect($res)->equal(1);

$obj = new \StdClass();
$res = prop('id', $obj, 2);
expect($res)->equal(2);

$obj = new \StdClass();
$obj->id = 1;
$obj->child = new \StdClass();
$obj->child->id = 2;
$res = propIn(['child', 'id'], $obj);
expect($res)->equal(2);

$obj = new \StdClass();
$obj->id = 1;
$obj->child = new \StdClass();
$res = propIn(['child', 'id'], $obj, 3);
expect($res)->equal(3);

$res = range(1, 3);
expect(toArray($res))->equal([1, 2, 3]);
php
$res = range(3, 1);
expect(toArray($res))->equal([3, 2, 1]);
php
expect(function () {
    toArray(range(1, 2, -1));
})->throw(\InvalidArgumentException::class);
expect(function () {
    toArray(range(2, 1, 1));
})->throw(\InvalidArgumentException::class);
php
$res = reduce(function ($acc, $v) {
    return $acc + $v;
}, range(1, 3), 0);
expect($res)->equal(6);
php
$res = reduceKeyValue(function ($acc, $kv) {
    [$key, $value] = $kv;
    return $acc . $key . $value;
}, fromPairs([['a', 1], ['b', 2]]), "");
expect($res)->equal("a1b2");
php
$res = reindex(function ($v) {
    return $v['id'];
}, [['id' => 2], ['id' => 3], ['id' => 1]]);
expect(toArrayWithKeys($res))->equal([2 => ['id' => 2], 3 => ['id' => 3], 1 => ['id' => 1]]);
php
$i = 0;
$res = retry(function () use(&$i) {
    $i += 1;
    if ($i <= 1) {
        throw new \Exception('bad');
    }
    return $i;
});
expect($res)->equal(2);
php
expect(function () {
    $i = 0;
    retry(function () use(&$i) {
        $i += 1;
        throw new \Exception((string) $i);
    }, 5);
})->throw('Exception', '6');
php
$i = 0;
expect(function () {
    $res = retry(function () use(&$i) {
        $i += 1;
        throw new \Exception((string) $i);
    }, function ($numRetries, \Throwable $t = null) {
        return $numRetries < 2;
    });
})->throw('Exception', '2');
php
$res = retry(function ($numRetries) {
    if (!$numRetries) {
        throw new Exception('bad');
    }
    return $numRetries;
}, 2);
expect($res)->equal(1);
php
$res = search(function ($v) {
    return $v['id'] == 2;
}, [['id' => 1], ['id' => 2], ['id' => 3]]);
expect($res)->equal(['id' => 2]);
php
$res = search(function ($v) {
    return false;
}, [['id' => 1], ['id' => 2], ['id' => 3]]);
expect($res)->equal(null);
php
$res = setIndex('a', 1, []);
expect($res['a'])->equal(1);
php
$res = setProp('a', 1, (object) []);
expect($res->a)->equal(1);
php
$sliced = slice(1, range(0, 4), 2);
expect(toArray($sliced))->equal([1, 2]);
php
$sliced = slice(2, range(0, 4));
expect(toArray($sliced))->equal([2, 3, 4]);
php
$i = 0;
$gen = function () use(&$i) {
    foreach (range(0, 4) as $v) {
        $i = $v;
        (yield $i);
    }
};
$sliced = toArray(slice(1, $gen(), 2));
expect($sliced)->equal([1, 2]);
expect($i)->equal(2);
php
$data = [['id' => 1, 'name' => 'A'], ['id' => 2, 'name' => 'B'], ['id' => 3, 'name' => 'C']];
$res = sortFromArray(Curried\index('id'), [2, 3, 1], $data);
expect(arrayMap(Curried\index('name'), $res))->equal(['B', 'C', 'A']);
php
expect(function () {
    $data = [['id' => 1]];
    $res = sortFromArray(Curried\index('id'), [], $data);
})->throw(\LogicException::class, 'Cannot sort element key 1 because it does not exist in the ordered elements.');
php
$res = spread(function ($a, $b) {
    return $a . $b;
}, ['a', 'b']);
expect($res)->equal('ab');
php
$res = arrayMap(Curried\spread(function (string $first, int $second) {
    return $first . $second;
}), [['a', 1], ['b', 2]]);
expect($res)->equal(['a1', 'b2']);
php
$res = take(2, range(0, 10));
expect(toArray($res))->equal([0, 1]);
php
$res = takeWhile(Curried\op('>')(0), [2, 1, 0, 1, 2]);
expect(toArray($res))->equal([2, 1]);
php
$loggedValues = [];
$res = tap(function (string $v) use(&$loggedValues) {
    $loggedValues[] = $v;
}, 'abc');
expect([$loggedValues[0], $res])->equal(['abc', 'abc']);
php
expect(function () {
    throwIf(function (int $value) {
        return new RuntimeException('Error: ' . $value);
    }, function (int $value) {
        return $value === 0;
    }, 0);
})->throw(RuntimeException::class, 'Error: 0');
php
$res = throwIf(function (int $value) {
    return new RuntimeException('Error: ' . $value);
}, function (int $value) {
    return $value === 0;
}, 1);
expect($res)->equal(1);
php
$res = toArray((function () {
    (yield 1);
    (yield 2);
    (yield 3);
})());
expect($res)->equal([1, 2, 3]);
php
$res = compose(toArray, id)((function () {
    (yield 1);
    (yield 2);
    (yield 3);
})());
expect($res)->equal([1, 2, 3]);
php
$res = toPairs(['a' => 1, 'b' => 2]);
expect(toArray($res))->equal([['a', 1], ['b', 2]]);
php
$data = ['a' => ['b' => ['c' => 3]]];
$data = updateIndexIn(['a', 'b', 'c'], function ($v) {
    return $v * $v;
}, $data);
expect($data)->equal(['a' => ['b' => ['c' => 9]]]);
php
expect(function () {
    $data = ['a' => ['b' => ['c' => 9]]];
    updateIndexIn(['a', 'c', 'c'], function () {
    }, $data);
})->throw(\RuntimeException::class, 'Could not updateIn because the keys a -> c -> c could not be found.');
php
$res = values(['a' => 1, 'b' => 2]);
expect(toArrayWithKeys($res))->equal([1, 2]);
php
$if = function ($v) {
    return $v == 3;
};
$then = function ($v) {
    return $v * $v;
};
$res = when($if, $then, 3);
expect($res)->equal(9);
php
$if = function ($v) {
    return $v == 3;
};
$then = function ($v) {
    return $v * $v;
};
$res = when($if, $then, 4);
expect($res)->equal(4);
php
$fn = withState(function ($state, $v) {
    return [$state + 1, $state . ': ' . $v];
}, 1);
$res = arrayMap($fn, iter('abcd'));
expect($res)->equal(['1: a', '2: b', '3: c', '4: d']);
php
$data = flip(iter('abcd'));
$res = within(['a', 'c'], $data);
expect(toArrayWithKeys($res))->equal(['a' => 0, 'c' => 2]);
php
$data = flip(iter('abcd'));
$res = without(['a', 'c'], $data);
expect(toArrayWithKeys($res))->equal(['b' => 1, 'd' => 3]);