24
24
use const INF ;
25
25
use function is_array ;
26
26
use function is_callable ;
27
+ use function is_numeric ;
27
28
use function is_object ;
29
+ use function is_string ;
28
30
use Iterator ;
29
31
use JsonSerializable ;
32
+ use function method_exists ;
30
33
use OutOfBoundsException ;
31
34
use const PHP_INT_MAX ;
32
35
use function property_exists ;
33
36
use ReturnTypeWillChange ;
34
37
use function sprintf ;
38
+ use UnexpectedValueException ;
35
39
36
40
/**
37
41
* Abstract immutable sequence with basic functional methods.
@@ -281,7 +285,7 @@ public function sorted(?callable $comparator = null): self
281
285
*
282
286
* @psalm-mutation-free
283
287
*/
284
- public function keyBy (string $ key ): ArrayList
288
+ public function pluck (string $ key ): ArrayList
285
289
{
286
290
return new ArrayList (function () use ($ key ) {
287
291
foreach ($ this as $ value ) {
@@ -294,6 +298,28 @@ public function keyBy(string $key): ArrayList
294
298
});
295
299
}
296
300
301
+ /**
302
+ * Uses the values found at the provided key as the key for the new Map.
303
+ *
304
+ * @return Map<mixed>
305
+ *
306
+ * @psalm-mutation-free
307
+ */
308
+ public function keyBy (string $ key ): Map
309
+ {
310
+ return new Map (function () use ($ key ) {
311
+ foreach ($ this as $ value ) {
312
+ if (is_array ($ value ) && array_key_exists ($ key , $ value ) && $ this ->isStringable ($ value [$ key ])) {
313
+ yield $ value [$ key ] => $ value ;
314
+ } elseif (is_object ($ value ) && property_exists ($ value , $ key ) && $ this ->isStringable ($ value ->$ key )) {
315
+ yield $ value ->$ key => $ value ;
316
+ } else {
317
+ throw new UnexpectedValueException ('Cannot convert the value to a string ' );
318
+ }
319
+ }
320
+ });
321
+ }
322
+
297
323
/**
298
324
* Joins the values within the sequence together with the provided glue. If the glue is null, it will be an empty string.
299
325
*/
@@ -497,4 +523,14 @@ public function preload(): void
497
523
$ this ->next ();
498
524
}
499
525
}
526
+
527
+ /**
528
+ * @param mixed $key
529
+ *
530
+ * @psalm-mutation-free
531
+ */
532
+ protected function isStringable ($ key ): bool
533
+ {
534
+ return is_string ($ key ) || is_numeric ($ key ) || (is_object ($ key ) && method_exists ($ key , '__toString ' ));
535
+ }
500
536
}
0 commit comments