Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin/generate-all.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
}

// Generate ImmutableCollection narrowing (Collection -> ImmutableCollection)
$immutableCollectionNarrowing = NarrowingGenerator::generateImmutableCollectionNarrowing($collectionContent, ['forEach']);
$immutableCollectionNarrowing = NarrowingGenerator::generateImmutableCollectionNarrowing($collectionContent, ['onEach']);
if (!NarrowingGenerator::writeBetweenMarkers($immutableCollectionFile, $immutableCollectionNarrowing)) {
echo "Failed to update ImmutableCollection.php\n";
exit(1);
}

// Generate WritableCollection narrowing (Collection -> ImmutableCollection)
$writableCollectionNarrowing = NarrowingGenerator::generateWritableCollectionTransformationNarrowing($collectionContent, ['forEach']);
$writableCollectionNarrowing = NarrowingGenerator::generateWritableCollectionTransformationNarrowing($collectionContent, ['onEach']);
if (!NarrowingGenerator::writeBetweenMarkers($writableCollectionFile, $writableCollectionNarrowing)) {
echo "Failed to update WritableCollection.php\n";
exit(1);
Expand Down
2 changes: 1 addition & 1 deletion bin/generate-list-narrowing.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
// 1. Mutation narrowing (WritableCollection -> WritableList)
// 2. Transformation narrowing (Collection -> ImmutableList)
$writableListMutationNarrowing = NarrowingGenerator::generateWritableListNarrowing($writableCollectionContent, []);
$writableListTransformationNarrowing = NarrowingGenerator::generateWritableListTransformationNarrowing($collectionContent, ['forEach']);
$writableListTransformationNarrowing = NarrowingGenerator::generateWritableListTransformationNarrowing($collectionContent, ['onEach']);
$writableListNarrowing = $writableListMutationNarrowing . "\n\n" . $writableListTransformationNarrowing;
if (!NarrowingGenerator::writeBetweenMarkers($writableListFile, $writableListNarrowing)) {
echo "Failed to update WritableList.php\n";
Expand Down
2 changes: 1 addition & 1 deletion bin/generate-map-narrowing.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}

// Generate WritableMap transformation narrowing (Map -> ImmutableMap)
$writableMapNarrowing = NarrowingGenerator::generateWritableMapTransformationNarrowing($mapContent, ['forEach', 'forEachKey', 'forEachValue']);
$writableMapNarrowing = NarrowingGenerator::generateWritableMapTransformationNarrowing($mapContent, ['onEach', 'onEachKey', 'onEachValue']);
if (!NarrowingGenerator::writeBetweenMarkers($writableMapFile, $writableMapNarrowing)) {
echo "Failed to update WritableMap.php\n";
exit(1);
Expand Down
8 changes: 4 additions & 4 deletions bin/generate-self-preserving.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
$end = NarrowingGenerator::SelfPreservingEndMarker;

// Type-changing methods (different element type, conversions, or chainable $this) are not narrowed.
$elementBlacklist = ['toImmutable', 'forEach', 'filterInstanceOf', 'map', 'mapNotNull', 'flatMap', 'flatten'];
$elementBlacklist = ['toImmutable', 'onEach', 'filterInstanceOf', 'map', 'mapNotNull', 'flatMap', 'flatten'];

// Set: + intersect/union/subtract (return Set, declared on Collection) and partition (array shape).
$set = NarrowingGenerator::generateSelfPreserving(
Expand Down Expand Up @@ -75,9 +75,9 @@
'mapValuesNotNull',
'flip',
'sortedWith',
'forEach',
'forEachKey',
'forEachValue',
'onEach',
'onEachKey',
'onEachValue',
];
$map = NarrowingGenerator::generateSelfPreserving(
$immutableMap,
Expand Down
2 changes: 1 addition & 1 deletion bin/generate-set-narrowing.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
// 1. Mutation narrowing (WritableCollection -> WritableSet)
// 2. Transformation narrowing (Collection -> ImmutableSet)
$writableSetMutationNarrowing = NarrowingGenerator::generateWritableSetNarrowing($writableCollectionContent, []);
$writableSetTransformationNarrowing = NarrowingGenerator::generateWritableSetTransformationNarrowing($collectionContent, ['forEach']);
$writableSetTransformationNarrowing = NarrowingGenerator::generateWritableSetTransformationNarrowing($collectionContent, ['onEach']);
$writableSetNarrowing = $writableSetMutationNarrowing . "\n\n" . $writableSetTransformationNarrowing;
if (!NarrowingGenerator::writeBetweenMarkers($writableSetFile, $writableSetNarrowing)) {
echo "Failed to update WritableSet.php\n";
Expand Down
9 changes: 7 additions & 2 deletions docs/collection/api/collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -393,9 +393,14 @@ Random order.
## Iteration

```php
forEach(Closure $action): Collection
onEach(Closure $action): Collection<E>
```
Execute action `(E, int): void` for each element. Returns the collection for chaining.
Execute action `(E, int): void` for each element and return the collection for chaining.

```php
forEach(Closure $action): void
```
Execute action `(E, int): void` for each element. Returns nothing — use `onEach()` when the collection is still needed.

## Conversion

Expand Down
27 changes: 21 additions & 6 deletions docs/collection/api/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,34 @@ All return new immutable maps, marked `#[NoDiscard]`.
## Iteration

```php
forEach(Closure $action): Map
onEach(Closure $action): Map<K,V>
```
Execute `(V, K): void` for each entry. Returns the map for chaining.
Execute `(V, K): void` for each entry and return the map for chaining.

```php
forEachKey(Closure $action): Map
onEachKey(Closure $action): Map<K,V>
```
Execute `(K): void` for each key. Returns the map for chaining.
Execute `(K): void` for each key and return the map for chaining.

```php
forEachValue(Closure $action): Map
onEachValue(Closure $action): Map<K,V>
```
Execute `(V): void` for each value. Returns the map for chaining.
Execute `(V): void` for each value and return the map for chaining.

```php
forEach(Closure $action): void
```
Execute `(V, K): void` for each entry. Returns nothing — use `onEach()` when the map is still needed.

```php
forEachKey(Closure $action): void
```
Execute `(K): void` for each key. Returns nothing — use `onEachKey()` when the map is still needed.

```php
forEachValue(Closure $action): void
```
Execute `(V): void` for each value. Returns nothing — use `onEachValue()` when the map is still needed.

## Conversion

Expand Down
3 changes: 2 additions & 1 deletion docs/collection/cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ listOf(['🍎','🍊','🍋'])->shuffled(); // random order
### Iteration & conversion

```php
listOf(['🍎','🍊'])->forEach(fn($e) => send($e)); // returns the list
listOf(['🍎','🍊'])->forEach(fn($e) => send($e)); // returns nothing
listOf(['🍎','🍊'])->onEach(fn($e) => send($e))->toSet(); // same walk, keeps the chain

listOf(['🍎','🍊','🍎'])->toSet(); // {🍎, 🍊}
setOf(['🍎','🍊'])->toList(); // [🍎, 🍊]
Expand Down
2 changes: 1 addition & 1 deletion docs/collection/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ foreach ($map as $key => $value) {
echo "$key = $value\n";
}

// returns itself for chaining
// returns nothing - use onEach() to keep chaining
$set->forEach(fn($el) => process($el));
```

Expand Down
4 changes: 2 additions & 2 deletions docs/collection/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,12 +411,12 @@ foreach ($map as $key => $value) {
}
```

All three methods return the map, so you can chain them mid-pipeline:
All three return nothing. Their `onEach()`, `onEachKey()` and `onEachValue()` counterparts return the map, so you can chain them mid-pipeline:

```php
$result = $map
->filter(fn($v) => $v > 0)
->forEach(fn($v, $k) => logger()->info("$k: $v"))
->onEach(fn($v, $k) => logger()->info("$k: $v"))
->mapValues(fn($v) => $v * 2);
```

Expand Down
10 changes: 9 additions & 1 deletion src/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,15 @@ public function shuffled(): Collection;
* @param Closure(E, int):void $action
* @return Collection<E>
*/
public function forEach(Closure $action): Collection;
public function onEach(Closure $action): Collection;

/**
* Executes the given action for each element.
* Returns nothing - chain with onEach() when the collection is still needed.
*
* @param Closure(E, int):void $action
*/
public function forEach(Closure $action): void;

// --- Conversion ---

Expand Down
6 changes: 2 additions & 4 deletions src/CollectionLogic.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,9 @@ public function shuffled(): ImmutableCollection
// --- Iteration ---

/** {@inheritDoc} */
public function forEach(Closure $action): static
public function onEach(Closure $action): static
{
foreach ($this as $i => $v) {
$action($v, $i);
}
$this->forEach($action);

return $this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ImmutableCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public function retainAll(iterable $elements): ImmutableCollection;
* @param Closure(E, int):void $action
* @return ImmutableCollection<E> The collection for chaining
*/
public function forEach(Closure $action): ImmutableCollection;
public function onEach(Closure $action): ImmutableCollection;

// --- Narrowing Start (auto-generated) ---

Expand Down
10 changes: 10 additions & 0 deletions src/IterableTerminalsLogic.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,4 +491,14 @@ public function joinToString(string $separator = ', ', string $prefix = '', stri

return $result . $postfix;
}

// --- Iteration ---

/** {@inheritDoc} */
public function forEach(Closure $action): void
{
foreach ($this as $i => $v) {
$action($v, $i);
}
}
}
2 changes: 1 addition & 1 deletion src/List/ImmutableList.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ public function retainAll(iterable $elements): ImmutableList;
* @param Closure(E, int):void $action
* @return ImmutableList<E> The collection for chaining
*/
public function forEach(Closure $action): ImmutableList;
public function onEach(Closure $action): ImmutableList;

/**
* Filter elements by predicate.
Expand Down
2 changes: 1 addition & 1 deletion src/List/ListInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ public function shuffled(): ListInterface;
* @param Closure(E, int):void $action
* @return ListInterface<E>
*/
public function forEach(Closure $action): ListInterface;
public function onEach(Closure $action): ListInterface;

/**
* Splits the collection into two collections based on a predicate.
Expand Down
2 changes: 1 addition & 1 deletion src/List/MutableList.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ public function clear(): MutableList;
* @param Closure(E, int):void $action
* @return MutableList<E> The collection itself for chaining
*/
public function forEach(Closure $action): MutableList;
public function onEach(Closure $action): MutableList;

/**
* Sets the element at the specified index.
Expand Down
2 changes: 1 addition & 1 deletion src/List/MutableTrackedList.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public function clear(): MutableTrackedList&TrackedResult;
* @param Closure(E, int):void $action
* @return MutableTrackedList<E>&TrackedResult The collection itself for chaining
*/
public function forEach(Closure $action): MutableTrackedList&TrackedResult;
public function onEach(Closure $action): MutableTrackedList&TrackedResult;

/**
* Sets the element at the specified index.
Expand Down
2 changes: 1 addition & 1 deletion src/List/WritableList.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public function clear(): WritableList;
* @param Closure(E, int):void $action
* @return WritableList<E> The collection itself for chaining
*/
public function forEach(Closure $action): WritableList;
public function onEach(Closure $action): WritableList;

/**
* Filter elements by predicate.
Expand Down
2 changes: 1 addition & 1 deletion src/List/WritableTrackedList.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public function clear(): WritableTrackedList&TrackedResult;
* @param Closure(E, int):void $action
* @return WritableTrackedList<E>&TrackedResult The collection itself for chaining
*/
public function forEach(Closure $action): WritableTrackedList&TrackedResult;
public function onEach(Closure $action): WritableTrackedList&TrackedResult;

// --- Narrowing End (auto-generated) ---
}
6 changes: 3 additions & 3 deletions src/Map/ImmutableMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -482,23 +482,23 @@ public function dropLastWhile(Closure $predicate): ImmutableMap;
* @param Closure(V, K):void $action
* @return ImmutableMap<K,V>
*/
public function forEach(Closure $action): ImmutableMap;
public function onEach(Closure $action): ImmutableMap;

/**
* Executes the given action for each key and returns the map for chaining.
*
* @param Closure(K):void $action
* @return ImmutableMap<K,V>
*/
public function forEachKey(Closure $action): ImmutableMap;
public function onEachKey(Closure $action): ImmutableMap;

/**
* Executes the given action for each value and returns the map for chaining.
*
* @param Closure(V):void $action
* @return ImmutableMap<K,V>
*/
public function forEachValue(Closure $action): ImmutableMap;
public function onEachValue(Closure $action): ImmutableMap;

// --- Narrowing End (auto-generated) ---
}
30 changes: 27 additions & 3 deletions src/Map/Map.php
Original file line number Diff line number Diff line change
Expand Up @@ -465,23 +465,47 @@ public function dropLastWhile(Closure $predicate): Map;
* @param Closure(V, K):void $action
* @return Map<K,V>
*/
public function forEach(Closure $action): Map;
public function onEach(Closure $action): Map;

/**
* Executes the given action for each key and returns the map for chaining.
*
* @param Closure(K):void $action
* @return Map<K,V>
*/
public function forEachKey(Closure $action): Map;
public function onEachKey(Closure $action): Map;

/**
* Executes the given action for each value and returns the map for chaining.
*
* @param Closure(V):void $action
* @return Map<K,V>
*/
public function forEachValue(Closure $action): Map;
public function onEachValue(Closure $action): Map;

/**
* Executes the given action for each entry.
* Returns nothing - chain with onEach() when the map is still needed.
*
* @param Closure(V, K):void $action
*/
public function forEach(Closure $action): void;

/**
* Executes the given action for each key.
* Returns nothing - chain with onEachKey() when the map is still needed.
*
* @param Closure(K):void $action
*/
public function forEachKey(Closure $action): void;

/**
* Executes the given action for each value.
* Returns nothing - chain with onEachValue() when the map is still needed.
*
* @param Closure(V):void $action
*/
public function forEachValue(Closure $action): void;

// --- Conversion ---

Expand Down
Loading
Loading