Skip to content

Commit dd19535

Browse files
committed
correctly implemented pluck and keyBy
1 parent 19cee79 commit dd19535

File tree

5 files changed

+53
-21
lines changed

5 files changed

+53
-21
lines changed

src/Types/AbstractCypherSequence.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@
2424
use const INF;
2525
use function is_array;
2626
use function is_callable;
27+
use function is_numeric;
2728
use function is_object;
29+
use function is_string;
2830
use Iterator;
2931
use JsonSerializable;
32+
use function method_exists;
3033
use OutOfBoundsException;
3134
use const PHP_INT_MAX;
3235
use function property_exists;
3336
use ReturnTypeWillChange;
3437
use function sprintf;
38+
use UnexpectedValueException;
3539

3640
/**
3741
* Abstract immutable sequence with basic functional methods.
@@ -281,7 +285,7 @@ public function sorted(?callable $comparator = null): self
281285
*
282286
* @psalm-mutation-free
283287
*/
284-
public function keyBy(string $key): ArrayList
288+
public function pluck(string $key): ArrayList
285289
{
286290
return new ArrayList(function () use ($key) {
287291
foreach ($this as $value) {
@@ -294,6 +298,28 @@ public function keyBy(string $key): ArrayList
294298
});
295299
}
296300

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+
297323
/**
298324
* Joins the values within the sequence together with the provided glue. If the glue is null, it will be an empty string.
299325
*/
@@ -497,4 +523,14 @@ public function preload(): void
497523
$this->next();
498524
}
499525
}
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+
}
500536
}

src/Types/CypherMap.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ public function getAsWGS843DPoint(string $key, $default = null): WGS843DPoint
230230
* @param iterable<Value> $iterable
231231
*
232232
* @return self<Value>
233+
*
234+
* @pure
233235
*/
234236
public static function fromIterable(iterable $iterable): CypherMap
235237
{
@@ -239,8 +241,16 @@ public static function fromIterable(iterable $iterable): CypherMap
239241
/**
240242
* @psalm-mutation-free
241243
*/
242-
public function keyBy(string $key): CypherList
244+
public function pluck(string $key): CypherList
245+
{
246+
return CypherList::fromIterable(parent::pluck($key));
247+
}
248+
249+
/**
250+
* @psalm-mutation-free
251+
*/
252+
public function keyBy(string $key): CypherMap
243253
{
244-
return CypherList::fromIterable(parent::keyBy($key));
254+
return CypherMap::fromIterable(parent::keyBy($key));
245255
}
246256
}

src/Types/Map.php

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,9 @@
2222
use function is_array;
2323
use function is_callable;
2424
use function is_iterable;
25-
use function is_numeric;
26-
use function is_object;
27-
use function is_string;
2825
use Laudis\Neo4j\Databags\Pair;
2926
use Laudis\Neo4j\Exception\RuntimeTypeException;
3027
use Laudis\Neo4j\TypeCaster;
31-
use function method_exists;
3228
use OutOfBoundsException;
3329
use function sprintf;
3430
use stdClass;
@@ -52,7 +48,7 @@ public function __construct($iterable = [])
5248
if (is_array($iterable)) {
5349
$i = 0;
5450
foreach ($iterable as $key => $value) {
55-
if (!$this->stringable($key)) {
51+
if (!$this->isStringable($key)) {
5652
$key = (string) $i;
5753
}
5854
/** @var string $key */
@@ -72,7 +68,7 @@ public function __construct($iterable = [])
7268
$it = is_callable($iterable) ? $iterable() : $iterable;
7369
/** @var mixed $key */
7470
foreach ($it as $key => $value) {
75-
if ($this->stringable($key)) {
71+
if ($this->isStringable($key)) {
7672
yield (string) $key => $value;
7773
} else {
7874
yield (string) $i => $value;
@@ -521,14 +517,4 @@ public static function fromIterable(iterable $iterable): Map
521517
{
522518
return new self($iterable);
523519
}
524-
525-
/**
526-
* @param mixed $key
527-
*
528-
* @psalm-mutation-free
529-
*/
530-
private function stringable($key): bool
531-
{
532-
return is_string($key) || is_numeric($key) || (is_object($key) && method_exists($key, '__toString'));
533-
}
534520
}

tests/Unit/CypherListTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ public function testKeyBy(): void
398398
$object,
399399
['x' => 'arrayX', 'y' => 'wrong'],
400400
'wrong',
401-
])->keyBy('x');
401+
])->pluck('x');
402402

403403
self::assertEquals(['stdClassX', 'arrayX'], $list->toArray());
404404
}

tests/Unit/CypherMapTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ public function testKeyBy(): void
493493
'x' => $object,
494494
'y' => ['x' => 'arrayX', 'y' => 'wrong'],
495495
'z' => 'wrong',
496-
])->keyBy('x');
496+
])->pluck('x');
497497

498498
self::assertEquals(['stdClassX', 'arrayX'], $list->toArray());
499499
}

0 commit comments

Comments
 (0)