1: <?php
2:
3: namespace Chromabits\Nucleus\Data;
4:
5: use Chromabits\Nucleus\Control\Maybe;
6: use Chromabits\Nucleus\Data\Interfaces\FoldableInterface;
7: use Chromabits\Nucleus\Data\Interfaces\FunctorInterface;
8: use Chromabits\Nucleus\Data\Interfaces\IterableInterface;
9: use Chromabits\Nucleus\Data\Interfaces\ListInterface;
10: use Chromabits\Nucleus\Data\Interfaces\MapInterface;
11: use Chromabits\Nucleus\Foundation\BaseObject;
12: use Chromabits\Nucleus\Foundation\Interfaces\ArrayableInterface;
13: use Chromabits\Nucleus\Meditation\Constraints\AbstractTypeConstraint;
14:
15: 16: 17: 18: 19: 20:
21: abstract class Iterable extends BaseObject implements
22: ArrayableInterface,
23: FunctorInterface,
24: FoldableInterface,
25: IterableInterface
26: {
27: 28: 29:
30: protected $size;
31:
32: 33: 34:
35: abstract public function getKeyType();
36:
37: 38: 39:
40: abstract public function getValueType();
41:
42: 43: 44: 45: 46:
47: abstract public function lookup($key);
48:
49: 50: 51: 52: 53:
54: abstract public function member($key);
55:
56: 57: 58: 59: 60:
61: public function includes($value)
62: {
63: return $this->find(function ($current) use ($value) {
64: return $current === $value;
65: })->isJust();
66: }
67:
68: 69: 70:
71: public function head()
72: {
73: return Maybe::fromJust($this->lookup(0));
74: }
75:
76: 77: 78:
79: public function last()
80: {
81: return Maybe::fromJust($this->lookup($this->size - 1));
82: }
83:
84: 85: 86: 87: 88:
89: abstract public function lookupIn($searchKeyPath);
90:
91: 92: 93: 94: 95:
96: abstract public function memberIn($searchKeyPath);
97:
98: 99: 100:
101: abstract public function toArray();
102:
103: 104: 105: 106: 107:
108: abstract public function fmap(callable $callable);
109:
110: 111: 112: 113: 114:
115: public function map(callable $callable)
116: {
117: return $this->fmap($callable);
118: }
119:
120: 121: 122: 123: 124:
125: abstract public function filter(callable $callable);
126:
127: 128: 129: 130: 131:
132: public function filterNot(callable $callable)
133: {
134: return $this->filter(
135: function ($value, $key, $iterable) use ($callable) {
136: return !$callable($value, $key, $iterable);
137: }
138: );
139: }
140:
141: 142: 143:
144: abstract public function reverse();
145:
146: 147: 148: 149: 150:
151: abstract public function sort(callable $comparator = null);
152:
153: 154: 155: 156: 157: 158:
159: public function sortBy(
160: callable $comparatorValueMapper,
161: callable $comparator = null
162: ) {
163: return $this->map($comparatorValueMapper)->sort($comparator);
164: }
165:
166: 167: 168: 169: 170:
171: abstract public function each(callable $sideEffect);
172:
173: 174: 175: 176: 177: 178:
179: abstract public function slice($begin, $end = null);
180:
181: 182: 183:
184: public function tail()
185: {
186: return $this->slice(1);
187: }
188:
189: 190: 191:
192: public function init()
193: {
194: return $this->slice(0, -1);
195: }
196:
197: 198: 199: 200: 201:
202: public function take($amount)
203: {
204:
205: if ($amount >= $this->size) {
206: return $this;
207: }
208:
209: return $this->slice(0, $amount);
210: }
211:
212: 213: 214: 215: 216:
217: public function takeLast($amount)
218: {
219: return $this->reverse()->take($amount);
220: }
221:
222: 223: 224: 225: 226:
227: abstract public function takeWhile(callable $predicate);
228:
229: 230: 231: 232: 233:
234: public function takeUntil(callable $predicate)
235: {
236: return $this->takeWhile(
237: function ($value, $key, $iterable) use ($predicate) {
238: return !$predicate($value, $key, $iterable);
239: }
240: );
241: }
242:
243: 244: 245:
246: public function count()
247: {
248: return $this->size;
249: }
250:
251: 252: 253: 254: 255:
256: public function find(callable $predicate)
257: {
258: $result = Maybe::nothing();
259:
260: $this->each(
261: function ($value, $key) use (
262: $predicate,
263: &$result
264: ) {
265: if ($predicate($value, $key, $this)) {
266: $result = Maybe::just($value);
267:
268: return false;
269: }
270:
271: return true;
272: }
273: );
274:
275: return $result;
276: }
277:
278: 279: 280: 281: 282:
283: public function findLast(callable $predicate)
284: {
285: return $this->reverse()->find($predicate);
286: }
287:
288: 289: 290:
291: abstract public function toMap();
292:
293: 294: 295:
296: abstract public function toList();
297:
298: 299: 300:
301: public function keys()
302: {
303:
304:
305: return $this
306: ->map(function ($value, $key) {
307: return $key;
308: })
309: ->toList();
310: }
311:
312: 313: 314:
315: public function values()
316: {
317:
318:
319: return $this
320: ->map(function ($value) {
321: return $value;
322: })
323: ->toList();
324: }
325:
326: 327: 328:
329: abstract public function entries();
330: }
331: