Skip to content

Commit f458564

Browse files
Громов Андрей Олеговичmbonneau
Громов Андрей Олегович
authored andcommitted
min operator (#64)
1 parent 0fc2280 commit f458564

File tree

7 files changed

+412
-1
lines changed

7 files changed

+412
-1
lines changed

demo/min/min-with-comparer.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
require_once __DIR__ . "/../bootstrap.php";
4+
5+
/* With a comparer */
6+
$comparer = function ($x, $y) {
7+
if ($x > $y) {
8+
return 1;
9+
} elseif ($x < $y) {
10+
return -1;
11+
}
12+
return 0;
13+
};
14+
15+
$source = \Rx\Observable::fromArray([1, 3, 5, 7, 9, 2, 4, 6, 8])
16+
->min($comparer);
17+
18+
$subscription = $source->subscribe($createStdoutObserver());

demo/min/min-with-comparer.php.expect

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Next value: 1
2+
Complete!

demo/min/min.php

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
require_once __DIR__ . "/../bootstrap.php";
4+
5+
/* Without comparer */
6+
$source = \Rx\Observable::fromArray([1, 3, 5, 7, 9, 2, 4, 6, 8])
7+
->min();
8+
9+
$subscription = $source->subscribe($createStdoutObserver());

demo/min/min.php.expect

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Next value: 1
2+
Complete!

lib/Rx/Observable.php

+19-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Rx\Operator\GroupByUntilOperator;
3434
use Rx\Operator\MapOperator;
3535
use Rx\Operator\FilterOperator;
36+
use Rx\Operator\MinOperator;
3637
use Rx\Operator\MaxOperator;
3738
use Rx\Operator\MaterializeOperator;
3839
use Rx\Operator\MergeAllOperator;
@@ -1505,7 +1506,24 @@ public function startWithArray(array $startArray)
15051506
return new StartWithArrayOperator($startArray);
15061507
});
15071508
}
1508-
1509+
1510+
/**
1511+
* Returns the minimum value in an observable sequence according to the specified comparer.
1512+
*
1513+
* @param callable $comparer
1514+
* @return AnonymousObservable
1515+
*
1516+
* @demo min/min.php
1517+
* @demo min/min-with-comparer.php
1518+
* @operator
1519+
* @reactivex min
1520+
*/
1521+
public function min(callable $comparer = null){
1522+
return $this->lift(function () use ($comparer) {
1523+
return new MinOperator($comparer);
1524+
});
1525+
}
1526+
15091527
/**
15101528
* Returns the maximum value in an observable sequence according to the specified comparer.
15111529
*

lib/Rx/Operator/MinOperator.php

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
namespace Rx\Operator;
4+
5+
use Rx\ObservableInterface;
6+
use Rx\Observer\CallbackObserver;
7+
use Rx\ObserverInterface;
8+
use Rx\SchedulerInterface;
9+
10+
class MinOperator implements OperatorInterface
11+
{
12+
/** @var callable|null */
13+
private $comparer;
14+
15+
/**
16+
* MinOperator constructor.
17+
* @param $comparer callable
18+
*/
19+
public function __construct(callable $comparer = null)
20+
{
21+
if ($comparer === null) {
22+
$comparer = function ($x, $y) {
23+
return $x > $y ? 1 : ($x < $y ? -1 : 0);
24+
};
25+
}
26+
27+
$this->comparer = $comparer;
28+
}
29+
30+
/**
31+
* @inheritDoc
32+
*/
33+
public function __invoke(
34+
ObservableInterface $observable,
35+
ObserverInterface $observer,
36+
SchedulerInterface $scheduler = null
37+
) {
38+
$previousMin = null;
39+
$comparing = false;
40+
41+
return $observable->subscribe(new CallbackObserver(
42+
function ($x) use (&$comparing, &$previousMin, $observer) {
43+
if (!$comparing) {
44+
$comparing = true;
45+
$previousMin = $x;
46+
47+
return;
48+
}
49+
50+
try {
51+
$result = call_user_func($this->comparer, $x, $previousMin);
52+
if ($result < 0) {
53+
$previousMin = $x;
54+
}
55+
} catch (\Exception $e) {
56+
$observer->onError($e);
57+
}
58+
},
59+
[$observer, 'onError'],
60+
function () use (&$comparing, &$previousMin, $observer) {
61+
if ($comparing) {
62+
$observer->onNext($previousMin);
63+
$observer->onCompleted();
64+
return;
65+
}
66+
67+
$observer->onError(new \Exception("Empty"));
68+
}
69+
), $scheduler);
70+
}
71+
}

0 commit comments

Comments
 (0)