Skip to content

Commit

Permalink
Fixed #4 (Distinct filtering support): added distinct method, fixed m…
Browse files Browse the repository at this point in the history
…inor doc comment issues
  • Loading branch information
Athari committed May 8, 2013
1 parent dcc66f1 commit c6f0bb7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 8 deletions.
29 changes: 28 additions & 1 deletion Tests/Unit/EnumerableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ function testAny_fromEnumerable ()

/** @covers YaLinqo\Enumerable::contains
*/
function testAny_contains ()
function testContains ()
{
// contains (value)
$this->assertEquals(
Expand All @@ -1282,6 +1282,33 @@ function testAny_contains ()
E::from(array(1, 2, 3))->contains(4));
}

/** @covers YaLinqo\Enumerable::distinct
*/
function testDistinct ()
{
// distinct ()
$this->assertEnumEquals(
array(),
E::from(array())->distinct());
$this->assertEnumEquals(
array(1, 2, 3),
E::from(array(1, 2, 3))->distinct());
$this->assertEnumEquals(
array(1, 2, 3),
E::from(array(1, 2, 3, 1, 2))->distinct());

// distinct (selector)
$this->assertEnumEquals(
array(),
E::from(array())->distinct('$v*$k'));
$this->assertEnumEquals(
array(3 => 1, 2 => 2, 1 => 5),
E::from(array(3 => 1, 2 => 2, 1 => 5))->distinct('$v*$k'));
$this->assertEnumEquals(
array(4 => 1, 1 => 3),
E::from(array(4 => 1, 2 => 2, 1 => 3))->distinct('$v*$k'));
}

#endregion

#region Pagination
Expand Down
36 changes: 29 additions & 7 deletions YaLinqo/Enumerable.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use YaLinqo, YaLinqo\collections as c, YaLinqo\exceptions as e;

// TODO: string syntax: select("new { ... }")
// TODO: linq.js must: Distinct[By], Except[By], Intersect, Union, Cast
// TODO: linq.js must: Except[By], Intersect, Union, Cast
// TODO: linq.js must: Zip, Concat, Insert, Let, Memoize, MemoizeAll, BufferWithCount, SequenceEqual, Reverse
// TODO: linq.js high: CascadeBreadthFirst, CascadeDepthFirst, Flatten, Scan, PreScan, Alternate, DefaultIfEmpty, Shuffle
// TODO: linq.js maybe: Pairwise, PartitionBy, TakeExceptLast, TakeFromLast, Share
Expand Down Expand Up @@ -800,7 +800,7 @@ public function count ($predicate = null)
/**
* <p><b>Syntax</b>: max ()
* <p>Returns the maximum value in a sequence of values.
* <p><b>Syntax</b>: max ([selector {{(v, k) ==> value}])
* <p><b>Syntax</b>: max (selector {{(v, k) ==> value})
* <p>Invokes a transform function on each element of a sequence and returns the maximum value.
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
* @throws \UnexpectedValueException If sequence contains no elements.
Expand All @@ -815,9 +815,9 @@ public function max ($selector = null)
}

/**
* <p><b>Syntax</b>: maxBy ()
* <p><b>Syntax</b>: maxBy (comparer {{(a, b) ==> diff})
* <p>Returns the maximum value in a sequence of values, using specified comparer.
* <p><b>Syntax</b>: maxBy ([selector {{(v, k) ==> value}])
* <p><b>Syntax</b>: maxBy (comparer {{(a, b) ==> diff}, selector {{(v, k) ==> value})
* <p>Invokes a transform function on each element of a sequence and returns the maximum value, using specified comparer.
* @param callback $comparer {(a, b) ==> diff} Difference between a and b: &lt;0 if a&lt;b; 0 if a==b; &gt;0 if a&gt;b
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
Expand All @@ -838,7 +838,7 @@ public function maxBy ($comparer, $selector = null)
/**
* <p><b>Syntax</b>: min ()
* <p>Returns the minimum value in a sequence of values.
* <p><b>Syntax</b>: min ([selector {{(v, k) ==> value}])
* <p><b>Syntax</b>: min (selector {{(v, k) ==> value})
* <p>Invokes a transform function on each element of a sequence and returns the minimum value.
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
* @throws \UnexpectedValueException If sequence contains no elements.
Expand All @@ -853,9 +853,9 @@ public function min ($selector = null)
}

/**
* <p><b>Syntax</b>: minBy ()
* <p><b>Syntax</b>: minBy (comparer {{(a, b) ==> diff})
* <p>Returns the minimum value in a sequence of values, using specified comparer.
* <p><b>Syntax</b>: minBy ([selector {{(v, k) ==> value}])
* <p><b>Syntax</b>: minBy (comparer {{(a, b) ==> diff}, selector {{(v, k) ==> value})
* <p>Invokes a transform function on each element of a sequence and returns the minimum value, using specified comparer.
* @param callback $comparer {(a, b) ==> diff} Difference between a and b: &lt;0 if a&lt;b; 0 if a==b; &gt;0 if a&gt;b
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
Expand Down Expand Up @@ -954,6 +954,28 @@ public function contains ($value)
return false;
}

/**
* <p><b>Syntax</b>: distinct ()
* <p>Returns distinct elements from a sequence.
* <p><b>Syntax</b>: distinct (selector {{(v, k) ==> value})
* <p>Invokes a transform function on each element of a sequence and returns distinct elements.
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
* @return Enumerable A sequence that contains distinct elements of the input sequence.
*/
public function distinct ($selector = null)
{
$selector = Utils::createLambda($selector, 'v,k', Functions::$value);

$dic = new c\Dictionary();
return $this->where(function ($v, $k) use ($dic, $selector) {
$key = call_user_func($selector, $v, $k);
if ($dic->offsetExists($key))
return false;
$dic->offsetSet($key, true);
return true;
});
}

#endregion

#region Pagination
Expand Down

0 comments on commit c6f0bb7

Please sign in to comment.