Skip to content

Commit c6f0bb7

Browse files
committed
Fixed #4 (Distinct filtering support): added distinct method, fixed minor doc comment issues
1 parent dcc66f1 commit c6f0bb7

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

Tests/Unit/EnumerableTest.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1268,7 +1268,7 @@ function testAny_fromEnumerable ()
12681268

12691269
/** @covers YaLinqo\Enumerable::contains
12701270
*/
1271-
function testAny_contains ()
1271+
function testContains ()
12721272
{
12731273
// contains (value)
12741274
$this->assertEquals(
@@ -1282,6 +1282,33 @@ function testAny_contains ()
12821282
E::from(array(1, 2, 3))->contains(4));
12831283
}
12841284

1285+
/** @covers YaLinqo\Enumerable::distinct
1286+
*/
1287+
function testDistinct ()
1288+
{
1289+
// distinct ()
1290+
$this->assertEnumEquals(
1291+
array(),
1292+
E::from(array())->distinct());
1293+
$this->assertEnumEquals(
1294+
array(1, 2, 3),
1295+
E::from(array(1, 2, 3))->distinct());
1296+
$this->assertEnumEquals(
1297+
array(1, 2, 3),
1298+
E::from(array(1, 2, 3, 1, 2))->distinct());
1299+
1300+
// distinct (selector)
1301+
$this->assertEnumEquals(
1302+
array(),
1303+
E::from(array())->distinct('$v*$k'));
1304+
$this->assertEnumEquals(
1305+
array(3 => 1, 2 => 2, 1 => 5),
1306+
E::from(array(3 => 1, 2 => 2, 1 => 5))->distinct('$v*$k'));
1307+
$this->assertEnumEquals(
1308+
array(4 => 1, 1 => 3),
1309+
E::from(array(4 => 1, 2 => 2, 1 => 3))->distinct('$v*$k'));
1310+
}
1311+
12851312
#endregion
12861313

12871314
#region Pagination

YaLinqo/Enumerable.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use YaLinqo, YaLinqo\collections as c, YaLinqo\exceptions as e;
55

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

817817
/**
818-
* <p><b>Syntax</b>: maxBy ()
818+
* <p><b>Syntax</b>: maxBy (comparer {{(a, b) ==> diff})
819819
* <p>Returns the maximum value in a sequence of values, using specified comparer.
820-
* <p><b>Syntax</b>: maxBy ([selector {{(v, k) ==> value}])
820+
* <p><b>Syntax</b>: maxBy (comparer {{(a, b) ==> diff}, selector {{(v, k) ==> value})
821821
* <p>Invokes a transform function on each element of a sequence and returns the maximum value, using specified comparer.
822822
* @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
823823
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
@@ -838,7 +838,7 @@ public function maxBy ($comparer, $selector = null)
838838
/**
839839
* <p><b>Syntax</b>: min ()
840840
* <p>Returns the minimum value in a sequence of values.
841-
* <p><b>Syntax</b>: min ([selector {{(v, k) ==> value}])
841+
* <p><b>Syntax</b>: min (selector {{(v, k) ==> value})
842842
* <p>Invokes a transform function on each element of a sequence and returns the minimum value.
843843
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
844844
* @throws \UnexpectedValueException If sequence contains no elements.
@@ -853,9 +853,9 @@ public function min ($selector = null)
853853
}
854854

855855
/**
856-
* <p><b>Syntax</b>: minBy ()
856+
* <p><b>Syntax</b>: minBy (comparer {{(a, b) ==> diff})
857857
* <p>Returns the minimum value in a sequence of values, using specified comparer.
858-
* <p><b>Syntax</b>: minBy ([selector {{(v, k) ==> value}])
858+
* <p><b>Syntax</b>: minBy (comparer {{(a, b) ==> diff}, selector {{(v, k) ==> value})
859859
* <p>Invokes a transform function on each element of a sequence and returns the minimum value, using specified comparer.
860860
* @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
861861
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
@@ -954,6 +954,28 @@ public function contains ($value)
954954
return false;
955955
}
956956

957+
/**
958+
* <p><b>Syntax</b>: distinct ()
959+
* <p>Returns distinct elements from a sequence.
960+
* <p><b>Syntax</b>: distinct (selector {{(v, k) ==> value})
961+
* <p>Invokes a transform function on each element of a sequence and returns distinct elements.
962+
* @param callback|null $selector {(v, k) ==> value} A transform function to apply to each element. Default: value.
963+
* @return Enumerable A sequence that contains distinct elements of the input sequence.
964+
*/
965+
public function distinct ($selector = null)
966+
{
967+
$selector = Utils::createLambda($selector, 'v,k', Functions::$value);
968+
969+
$dic = new c\Dictionary();
970+
return $this->where(function ($v, $k) use ($dic, $selector) {
971+
$key = call_user_func($selector, $v, $k);
972+
if ($dic->offsetExists($key))
973+
return false;
974+
$dic->offsetSet($key, true);
975+
return true;
976+
});
977+
}
978+
957979
#endregion
958980

959981
#region Pagination

0 commit comments

Comments
 (0)