PHPackages                             talesoft/tale-iterator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. talesoft/tale-iterator

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

talesoft/tale-iterator
======================

A basic, PSR-7 compatible stream utility library

0.1.1(7y ago)33.6kMITPHPPHP &gt;=7.1.0

Since Aug 4Pushed 7y ago3 watchersCompare

[ Source](https://github.com/Talesoft/tale-iterator)[ Packagist](https://packagist.org/packages/talesoft/tale-iterator)[ Docs](http://docs.talesoft.codes/php/tale/iterator)[ RSS](/packages/talesoft-tale-iterator/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (2)Dependencies (1)Versions (3)Used By (0)

[![Packagist](https://camo.githubusercontent.com/484050f5080c307cebb6cf75bf085ba54a0ba4e41aa525a1e5deab8420205011/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f74616c65736f66742f74616c652d6974657261746f722e7376673f7374796c653d666f722d7468652d6261646765)](https://packagist.org/packages/talesoft/tale-iterator)[![License](https://camo.githubusercontent.com/8a6330d56eabf0a8917d29622f0d503aaf13000a52f0b65820befcec6a41abfb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f54616c65736f66742f74616c652d6974657261746f722e7376673f7374796c653d666f722d7468652d6261646765)](https://github.com/Talesoft/tale-iterator/blob/master/LICENSE.md)[![CI](https://camo.githubusercontent.com/a3f571486e921a401e7dcec41e999b41b6eb4e568f5a37e58db40a116bf21f8f/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f54616c65736f66742f74616c652d6974657261746f722e7376673f7374796c653d666f722d7468652d6261646765)](https://travis-ci.org/Talesoft/tale-iterator)[![Coverage](https://camo.githubusercontent.com/487c39be62c44a63bf2e1cc629dbee64a6af99ff3e1ed666267abf738c4a6596/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636c696d6174652f636f7665726167652f54616c65736f66742f74616c652d6974657261746f722e7376673f7374796c653d666f722d7468652d6261646765)](https://codeclimate.com/github/Talesoft/tale-iterator)

Tale Iterator
=============

[](#tale-iterator)

What is Tale Iterator?
----------------------

[](#what-is-tale-iterator)

Tale Iterator extends the SPL iterators by some more, useful iterators for common use-cases.

Installation
------------

[](#installation)

```
composer require talesoft/tale-iterator
```

Usage
-----

[](#usage)

### MapIterator

[](#mapiterator)

Maps values by a `map()`-method. You mostly want to extend it and override the `map()`-method.

Stack with `FlipIterator` to map keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\MapIterator;

$values = new \ArrayIterator(range(0, 5));
$mapper = new class($values) extends MapIterator
{
    public function map()
    {
        return sprintf('Value %d', parent::map());
    }
};

var_dump(iterator_to_array($mapper));
/*
array(6) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 3"
  [4] => string(7) "Value 4"
  [5] => string(7) "Value 5"
}
*/
```

### CallbackMapIterator

[](#callbackmapiterator)

Maps values by specifying a simple callback.

Stack with `FlipIterator` to map keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\CallbackMapIterator;

$values = new \ArrayIterator(range(0, 5));
$mapper = new CallbackMapIterator($values, function (int $number) {
    return sprintf('Value %d', $number);
});

var_dump(iterator_to_array($mapper));
/*
array(6) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 3"
  [4] => string(7) "Value 4"
  [5] => string(7) "Value 5"
}
*/
```

### FilterIterator

[](#filteriterator)

Filters values by an `accept()`-method. You mostly want to extend it and override the `accept()`-method. **It will preserve keys!**. If you want to reset the keys, chain a `ValueIterator` as shown below.

Stack with `FlipIterator` to filter keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\FilterIterator;

$values = new \ArrayIterator(range(0, 5));
$filterer = new class($values) extends FilterIterator
{
    public function accept(): bool
    {
        return parent::current() !== 4;
    }
};

var_dump(iterator_to_array($filterer));
/*
array(5) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 3"
  [5] => string(7) "Value 5"
}
*/
```

### CallbackFilterIterator

[](#callbackfilteriterator)

Filters values by specifying a simple callback.

Stack with `FlipIterator` to filter keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\CallbackFilterIterator;

$values = new \ArrayIterator(range(0, 5));
$filterer = new CallbackFilterIterator($values, function (int $number) {
    return $number !== 3;
});

var_dump(iterator_to_array($filterer));
/*
array(5) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [4] => string(7) "Value 4"
  [5] => string(7) "Value 5"
}
*/
```

> **Note:**
>
> PHP already has a FilterIterator and a CallbackFilterIterator, but it only accepts instances of \\Iterator, which doesn't include \\IteratorAggregate instances. This one accepts instances of \\Traversable, which includes all iterables except for objects and native arrays (which are covered, too, keep reading). It uses the same API as the PHP implementation, though!

### IterableIterator

[](#iterableiterator)

This is a small utility iterator that turns any `iterable` into a valid iterator. It's equivalent to an [\\IteratorIterator](http://php.net/manual/de/class.iteratoriterator.php), that normalizes the passed iterable to

`$iterable instanceof \Traversable ? $iterable : new \ArrayIterator($iterable)`.

With this iterator, you can pass any kind of iterable, arrays, objects, generators etc. to an iterator that only accepts \\Iterator instances easily.

This is useful for PHPs SPL iterators or other iterator implementations that don't leverage `iterable` or `\Traversable` and rely on `\Iterator` only and/or do this for a very good reason

```
use Tale\Iterator\IterableIterator;

$values = new IterableIterator(['a', 'b', 'c', 'd', 'e']);
$filterer = new \RegexIterator($values, '/[a-c]/');

var_dump(iterator_to_array($filterer));
/*
array(3) {
  [0] => string(1) "a"
  [1] => string(1) "b"
  [2] => string(1) "c"
}
*/
```

### ValueIterator

[](#valueiterator)

This is basically `array_values()` for iterators. This is useful to e.g. reset the keys for `FilterIterator` outputs.

```
use Tale\Iterator\CallbackFilterIterator;
use Tale\Iterator\ValueIterator;

$values = new \ArrayIterator(range(0, 5));
$filterer = new CallbackFilterIterator($values, function (int $number) {
    return $number !== 3;
});
$resetter = new ValueIterator($filterer);

var_dump(iterator_to_array($resetter));
/*
array(5) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 4"
  [4] => string(7) "Value 5"
}

Compare the output to the CallbackFilterIterator example above
and notice the keys!
*/
```

### KeyIterator

[](#keyiterator)

This is basically `array_keys()` for iterators. This is useful if you want to get a clean list of the inner iterators keys.

```
use Tale\Iterator\KeyIterator;

$values = new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 3]);
$keys = new KeyIterator($values);

var_dump(iterator_to_array($keys));
/*
array(3) {
  [0] => string(1) "a"
  [1] => string(1) "b"
  [2] => string(1) "c"
}

Compare the output to the CallbackFilterIterator example above
and notice the keys!
*/
```

### FlipIterator

[](#flipiterator)

This iterator will flip keys and values. This is often useful if you want outer iterators act on keys rather than on values.

Through the way iterators work, as long as you don't flatten the iterator to an array, duplicate values won't result on dropped keys! Notice the second example to understand what I mean.

```
use Tale\Iterator\FlipIterator;

$values = new \ArrayIterator(range('a', 'e'));
$flipper = new FlipIterator($values);

var_dump(iterator_to_array($flipper));
/*
array(5) {
  'a' => int(0)
  'b' => int(1)
  'c' => int(2)
  'd' => int(3)
  'e' => int(4)
}
*/
```

With `array_flip`, duplicate values will lead to dropped keys, as array keys have to be unique. With iterators, this isn't the case as long as you don't actually flatten it!

```
use Tale\Iterator\FlipIterator;

$values = new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 2, 'd' => 2]);
$flipper = new FlipIterator($values);

//Do something with $flipper, like, iterator stuff

$reverseFlipper = new FlipIterator($flipper);

var_dump(iterator_to_array($reverseFlipper));
/*
array(4) {
  'a' => int(1)
  'b' => int(2)
  'c' => int(2)
  'd' => int(2)
}
*/
```

### FormatIterator

[](#formatiterator)

This is basically `sprintf($format, $current)` on each value in the iterator.

Stack with `FlipIterator` to format keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\FormatIterator;

$values = new \ArrayIterator(range(0, 5));
$formatter = new FormatIterator($values, 'Value %d');

var_dump(iterator_to_array($formatter));
/*
array(6) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 3"
  [4] => string(7) "Value 4"
  [5] => string(7) "Value 5"
}
*/
```

### PrefixIterator

[](#prefixiterator)

This is `$prefix.$current` for each value in the iterator.

Stack with `FlipIterator` to prefix keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\PrefixIterator;

$values = new \ArrayIterator(range(0, 5));
$prefixer = new PrefixIterator($values, 'Value ');

var_dump(iterator_to_array($prefixer));
/*
array(6) {
  [0] => string(7) "Value 0"
  [1] => string(7) "Value 1"
  [2] => string(7) "Value 2"
  [3] => string(7) "Value 3"
  [4] => string(7) "Value 4"
  [5] => string(7) "Value 5"
}
*/
```

### SuffixIterator

[](#suffixiterator)

This is `$current.$suffix` for each value in the iterator.

Stack with `FlipIterator` to suffix keys (see "How do I XYZ" at the bottom of this README)

```
use Tale\Iterator\SuffixIterator;

$values = new \ArrayIterator(range(0, 5));
$suffixer = new SuffixIterator($values, ' Value');

var_dump(iterator_to_array($suffixer));
/*
array(11) {
  [0] => string(7) "0 Value"
  [1] => string(7) "1 Value"
  [2] => string(7) "2 Value"
  [3] => string(7) "3 Value"
  [4] => string(7) "4 Value"
  [5] => string(7) "5 Value"
}
*/
```

### IndexIterator

[](#indexiterator)

This iterator counts an independent index during iteration and makes it available. This is useful to count the amount of iterations, mostly. `ValueIterator` and `KeyIterator` use this to reset the keys.

```
use Tale\Iterator\IndexIterator;

$values = new \ArrayIterator(['a' => 'b', 'b' => 'c', 'c' => 'd']);
$indexer = new IndexIterator($values);

foreach ($indexer as $key => $value) {
    $i = $indexer->getIndex();
    echo "{$key} => {$value} - at index: {$i}\n";
}
/*
a => b - at index: 0
b => c - at index: 1
c => d - at index: 2
*/
```

### How to do XYZ?

[](#how-to-do-xyz)

#### How to map keys instead of values?

[](#how-to-map-keys-instead-of-values)

Easy, through chaining a MapIterator and FlipIterators! Notice this doesn't create any additional overhead except for function calls. The internal array is as no point copied or even modified.

```
use Tale\Iterator\FlipIterator;
use Tale\Iterator\CallbackMapIterator;

$values = new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]);
$mapper = new FlipIterator(
    new CallbackMapIterator(
        new FlipIterator($values),
        function (string $key) {
            return "Key {$key}";
        }
    )
);

var_dump(iterator_to_array($mapper));
/*
array(4) {
  'Key a' => int(1)
  'Key b' => int(2)
  'Key c' => int(3)
  'Key d' => int(4)
}
*/
```

#### How to filter keys instead of values?

[](#how-to-filter-keys-instead-of-values)

Here, again, the FlipIterator does everything you need!

```
use Tale\Iterator\FlipIterator;
use Tale\Iterator\CallbackFilterIterator;

$values = new \ArrayIterator(['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]);
$mapper = new FlipIterator(
    new CallbackFilterIterator(
        new FlipIterator($values),
        function (string $key) {
            return $key !== 'b';
        }
    )
);

var_dump(iterator_to_array($mapper));
/*
array(4) {
  'a' => int(1)
  'c' => int(3)
  'd' => int(4)
}
*/
```

###  Health Score

27

—

LowBetter than 47% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~19 days

Total

2

Last Release

2868d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/75a80e0830e63c723808d021d3a1648a2643db60f4ac2e40842da05f227f956b?d=identicon)[TorbenKoehn](/maintainers/TorbenKoehn)

---

Top Contributors

[![TorbenKoehn](https://avatars.githubusercontent.com/u/1403556?v=4)](https://github.com/TorbenKoehn "TorbenKoehn (7 commits)")

---

Tags

iteratormap iteratorsprintf-iteratorprefix-iteratorsuffix-iterator

### Embed Badge

![Health badge](/badges/talesoft-tale-iterator/health.svg)

```
[![Health](https://phpackages.com/badges/talesoft-tale-iterator/health.svg)](https://phpackages.com/packages/talesoft-tale-iterator)
```

###  Alternatives

[nikic/iter

Iteration primitives using generators

1.1k6.2M53](/packages/nikic-iter)[loophp/collection

A (memory) friendly, easy, lazy and modular collection class.

744730.3k15](/packages/loophp-collection)[athari/yalinqo

YaLinqo, a LINQ-to-objects library for PHP

4581.2M5](/packages/athari-yalinqo)[ihor/nspl

Non-standard PHP library (NSPL) - functional primitives toolbox and more

375369.1k](/packages/ihor-nspl)[ginq/ginq

LINQ to Object inspired DSL for PHP

192258.2k3](/packages/ginq-ginq)[chdemko/sorted-collections

Sorted Collections for PHP &gt;= 8.4

222.6M3](/packages/chdemko-sorted-collections)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
