Skip to content

Commit f965945

Browse files
Add ary function which ignores arguments over the supplied number (#215)
* Add `ary`, a function which ignores arguments over the supplied number Added function which defines a function of an arbitry number of arguments and calls the provided callable with only the given number of arguments As suggested by @lstrojny, using the name `ary`, like in https://lodash.com/docs/4.17.15#ary * Added test for `ary` function * Fixed errors spit by vendor/bin/phpcs * Fix implementation and tests
1 parent 08e136a commit f965945

File tree

6 files changed

+106
-0
lines changed

6 files changed

+106
-0
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"autoload": {
2626
"psr-4": {"Functional\\": "src/Functional"},
2727
"files": [
28+
"src/Functional/Ary.php",
2829
"src/Functional/Average.php",
2930
"src/Functional/ButLast.php",
3031
"src/Functional/Capture.php",

docs/functional-php.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,26 @@ $partiallyAppliedSubtractor = partial_right($subtractor, 10);
356356
$partiallyAppliedSubtractor(20); // -> 10
357357
```
358358

359+
## ary()
360+
361+
`Functional\ary` (as in arity) takes a `callable` and a count and calls the `callable` with
362+
that many arguments using `take_left` if positive, or `take_right` if negative.
363+
Throws if passed 0.
364+
365+
For example:
366+
367+
```php
368+
use function Functional\ary;
369+
use function Functional\map;
370+
371+
# This fails because map calls it's callable with the element,
372+
# index and the whole collection
373+
# map($array, 'ucfirst');
374+
375+
# Using `ary`
376+
map($array, ary('ucfirst', 1')); # Passes only the first argument to `ucfirst`
377+
```
378+
359379
## partial_any()
360380

361381
There is a third function in the family called `partial_any`. Unlike its siblings it doesn’t automatically merge but it

src/Functional/Ary.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/**
4+
* @package Functional-php
5+
* @author Hugo Sales <hugo@fc.up.pt>
6+
* @copyright 2020 Hugo Sales
7+
* @license https://opensource.org/licenses/MIT MIT
8+
* @link https://github.com/lstrojny/functional-php
9+
*/
10+
11+
namespace Functional;
12+
13+
use Functional\Exceptions\InvalidArgumentException;
14+
use Traversable;
15+
16+
/**
17+
* Call $func with only abs($count) arguments, taken either from the
18+
* left or right depending on the sign
19+
*/
20+
function ary(callable $func, int $count): callable
21+
{
22+
InvalidArgumentException::assertNonZeroInteger($count, __FUNCTION__);
23+
24+
return function (...$args) use ($func, $count) {
25+
if ($count > 0) {
26+
return $func(...take_left($args, $count));
27+
} else if ($count < 0) {
28+
return $func(...take_right($args, -$count));
29+
}
30+
};
31+
}

src/Functional/Exceptions/InvalidArgumentException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,13 @@ private static function assertCollectionAlike($collection, $className, $callee,
280280
}
281281
}
282282

283+
public static function assertNonZeroInteger($value, $callee)
284+
{
285+
if (!\is_int($value) || $value == 0) {
286+
throw new static(\sprintf('%s expected parameter %d to be non-zero', $callee, $value));
287+
}
288+
}
289+
283290
private static function getType($value)
284291
{
285292
return \is_object($value) ? \get_class($value) : \gettype($value);

src/Functional/Functional.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
final class Functional
1414
{
15+
16+
/**
17+
* @see \Function\ary
18+
*/
19+
const ary = '\Functional\ary';
20+
1521
/**
1622
* @see \Functional\average
1723
*/

tests/Functional/AryTest.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/**
4+
* @package Functional-php
5+
* @author Hugo Sales <hugo@fc.up.pt>
6+
* @copyright 2020 Hugo Sales
7+
* @license https://opensource.org/licenses/MIT MIT
8+
* @link https://github.com/lstrojny/functional-php
9+
*/
10+
11+
namespace Functional\Tests;
12+
13+
use function Functional\ary;
14+
use Functional\Exceptions\InvalidArgumentException;
15+
16+
class AryTest extends AbstractTestCase
17+
{
18+
19+
public function test()
20+
{
21+
$f = function ($a = 0, $b = 0, $c = 0) {
22+
return $a + $b + $c;
23+
};
24+
25+
$this->assertSame(5, $f(5));
26+
$this->assertSame(5, ary($f, 1)(5));
27+
$this->assertSame(5, ary($f, 1)(5));
28+
$this->assertSame(6, ary($f, -1)(6));
29+
$this->assertSame(7, ary($f, 2)(5, 2));
30+
}
31+
32+
public function testException()
33+
{
34+
$this->expectException(InvalidArgumentException::class);
35+
$f = function ($a = 0, $b = 0, $c = 0) {
36+
return $a + $b + $c;
37+
};
38+
39+
ary($f, 0)(5);
40+
}
41+
}

0 commit comments

Comments
 (0)