Skip to content

Commit 9a85ced

Browse files
committed
optimized distinct() operator
1 parent 40880cf commit 9a85ced

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

lib/Rx/Operator/DistinctOperator.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,8 @@ class DistinctOperator implements OperatorInterface
1818

1919
public function __construct(callable $keySelector = null, callable $comparer = null)
2020
{
21-
22-
$this->comparer = $comparer ?: function ($x, $y) {
23-
return $x == $y;
24-
};
25-
21+
$this->comparer = $comparer;
2622
$this->keySelector = $keySelector;
27-
2823
}
2924

3025
/**
@@ -43,15 +38,22 @@ function ($value) use ($observer, &$values) {
4338
try {
4439
$key = $this->keySelector ? call_user_func($this->keySelector, $value) : $value;
4540

46-
foreach ($values as $v) {
47-
$comparerEquals = call_user_func($this->comparer, $key, $v);
41+
if ($this->comparer) {
42+
foreach ($values as $v) {
43+
$comparerEquals = call_user_func($this->comparer, $key, $v);
4844

49-
if ($comparerEquals) {
45+
if ($comparerEquals) {
46+
return;
47+
}
48+
}
49+
$values[] = $key;
50+
} else {
51+
if (array_key_exists($key, $values)) {
5052
return;
5153
}
54+
$values[$key] = null;
5255
}
5356

54-
$values[] = $key;
5557
$observer->onNext($value);
5658

5759
} catch (\Exception $e) {

test/Rx/Functional/Operator/DistinctTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,45 @@ public function distinct_CustomKey_some_throw()
353353

354354
}
355355

356+
/**
357+
* @test
358+
*/
359+
public function distinct_CustomKey_and_CustomComparer_some_duplicates()
360+
{
361+
362+
$xs = $this->createHotObservable([
363+
onNext(280, ['id' => 4]),
364+
onNext(300, ['id' => 2]),
365+
onNext(350, ['id' => 12]),
366+
onNext(380, ['id' => 3]),
367+
onNext(400, ['id' => 24]),
368+
onCompleted(420)
369+
]);
370+
371+
$results = $this->scheduler->startWithCreate(function () use ($xs) {
372+
return $xs->distinctKey(
373+
function ($x) {
374+
return $x['id'];
375+
},
376+
$this->modComparer(10)
377+
)->map(function ($x) {
378+
return $x['id'];
379+
});
380+
});
381+
382+
$this->assertMessages([
383+
onNext(280, 4),
384+
onNext(300, 2),
385+
onNext(380, 3),
386+
onCompleted(420)
387+
], $results->getMessages());
388+
389+
$this->assertSubscriptions([
390+
subscribe(200, 420)
391+
], $xs->getSubscriptions());
392+
393+
}
394+
356395

357396
public function modComparer($mod)
358397
{

0 commit comments

Comments
 (0)