GroupByIterator   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 2
dl 0
loc 65
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 3
A key() 0 4 1
A gotoNextGroup() 0 7 2
A valid() 0 4 1
A current() 0 13 2
A next() 0 6 1
A rewind() 0 6 1
1
<?php
2
3
namespace itertools;
4
5
use NoRewindIterator;
6
use InvalidArgumentException;
7
use IteratorIterator;
8
9
10
class GroupByIterator extends IteratorIterator
11
{
12
	protected $comparator;
13
	protected $currentGroupIterator;
14
	protected $groupIndex;
15
16
	public function __construct($innerIterable, $comparator = null)
17
	{
18
		parent::__construct(IterUtil::asIterator($innerIterable));
19
		if(null === $comparator) {
20
			$comparator = function($value) { return $value; };
21
		}
22
		if(!is_callable($comparator)) {
23
			throw new InvalidArgumentException('Comparator must be a callable');
24
		}
25
		$this->comparator = $comparator;
26
		$this->groupIndex = 0;
27
	}
28
29
	public function key()
30
	{
31
		return $this->groupIndex;
32
	}
33
34
	protected function gotoNextGroup()
35
	{
36
		$currentGroupIterator = $this->current();
37
		while($currentGroupIterator->valid()) {
38
			$currentGroupIterator->next();
39
		}
40
	}
41
42
	public function valid()
43
	{
44
		return $this->getInnerIterator()->valid();
45
	}
46
47
	public function current()
48
	{
49
		if(null !== $this->currentGroupIterator) {
50
			return $this->currentGroupIterator;
51
		}
52
		$comparator = $this->comparator;
53
		$currentComparatorResult = call_user_func($this->comparator, $this->getInnerIterator()->current());
54
		$this->currentGroupIterator = new TakeWhileIterator(new NoRewindIterator($this->getInnerIterator()), function($value) use ($comparator, $currentComparatorResult) {
55
			return call_user_func($comparator, $value) == $currentComparatorResult;
56
		});
57
		$this->currentGroupIterator->rewind();
58
		return $this->currentGroupIterator;
59
	}
60
61
	public function next()
62
	{
63
		$this->gotoNextGroup();
64
		$this->currentGroupIterator = null;
65
		$this->groupIndex += 1;
66
	}
67
68
	public function rewind()
69
	{
70
		$this->currentGroupIterator = null;
71
		$this->groupIndex = 0;
72
		parent::rewind();
73
	}
74
}
75
76