Skip to content

Commit

Permalink
Add isEmpty() function
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Nov 10, 2017
1 parent b922e63 commit fed36b4
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ list the function signatures as an overview:
void apply(callable $function, iterable $iterable)
string join(string $separator, iterable $iterable)
int count(iterable $iterable)
bool isEmpty(iterable $iterable)
mixed recurse(callable $function, $iterable)
array toArray(iterable $iterable)
array toArrayWithKeys(iterable $iterable)
Expand Down
30 changes: 28 additions & 2 deletions src/iter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace iter;

use Traversable;
use Countable;

/**
* Creates an iterable containing all numbers between the start and end value
Expand Down Expand Up @@ -903,12 +904,12 @@ function join($separator, $iterable) {
* iter\count(iter\flatten([1, 2, 3, [4, [[[5, 6], 7]]], 8]))
* => 8
*
* @param array|Traversable|\Countable $iterable The iterable to count
* @param array|Traversable|Countable $iterable The iterable to count
*
* @return int
*/
function count($iterable) {
if (is_array($iterable) || $iterable instanceof \Countable) {
if (\is_array($iterable) || $iterable instanceof Countable) {
return \count($iterable);
}
if (!$iterable instanceof \Traversable) {
Expand All @@ -923,6 +924,31 @@ function count($iterable) {
return $count;
}

/**
* Determines whether iterable is empty.
*
* If the iterable implements Countable, its count() method will be used.
* Calling isEmpty() does not drain iterators, as only the valid() method will
* be called.
*
* @param array|Traversable|Countable $iterable
* @return bool
*/
function isEmpty($iterable) {
if (\is_array($iterable) || $iterable instanceof \Countable) {
return count($iterable) == 0;
}

if ($iterable instanceof \Iterator) {
return !$iterable->valid();
} else if ($iterable instanceof \IteratorAggregate) {
return !$iterable->getIterator()->valid();
} else {
throw new \InvalidArgumentException(
'Argument must be iterable or implement Countable');
}
}

/**
* Recursively applies a function, working on entire iterables rather than
* individual values.
Expand Down
13 changes: 13 additions & 0 deletions test/iterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,15 @@ public function testCount() {
$this->assertSame(42, count(new _CountableTestDummy));
}

public function testIsEmpty() {
$this->assertTrue(isEmpty([]));
$this->assertFalse(isEmpty([null]));
$this->assertTrue(isEmpty(toArray([])));
$this->assertFalse(isEmpty(toArray([null])));
$this->assertTrue(isEmpty(repeat(42, 0)));
$this->assertFalse(isEmpty(repeat(42)));
}

public function testToArray() {
$this->assertSame([1, 2, 3], toArray(['a' => 1, 'b' => 2, 'c' => 3]));
$this->assertSame(
Expand Down Expand Up @@ -503,6 +512,10 @@ function() { _assertAllIterable([[], new \stdClass()]); },
function() { return count(new \stdClass()); },
'Argument must be iterable or implement Countable'
];
yield [
function() { return isEmpty(new \stdClass()); },
'Argument must be iterable or implement Countable'
];
yield [
function() { return toIter(new \stdClass()); },
'Argument must be iterable'
Expand Down

0 comments on commit fed36b4

Please sign in to comment.