Skip to content

Latest commit

 

History

History
448 lines (381 loc) · 49.8 KB

File metadata and controls

448 lines (381 loc) · 49.8 KB

IterToolsLogo Logo

IterTools - PHP Iteration Tools to Power Up Your Loops

Inspired by Python—designed for PHP.

Coverage Status License Latest Stable Version Downloads

Features

IterTools makes you an iteration superstar by providing two types of tools:

  • Loop iteration tools
  • Stream iteration tools

Loop Iteration Tools Example

foreach (Multi::zip(['a', 'b'], [1, 2]) as [$letter, $number]) {
    print($letter . $number);  // a1, b2
}

Stream Iteration Tools Example

$result = Stream::of([1, 1, 2, 2, 3, 4, 5])
    ->distinct()                 // [1, 2, 3, 4, 5]
    ->map(fn ($x) => $x**2)      // [1, 4, 9, 16, 25]
    ->filter(fn ($x) => $x < 10) // [1, 4, 9]
    ->toSum();                   // 14

All functions work on iterable collections:

  • array (type)
  • Generator (type)
  • Iterator (interface)
  • Traversable (interface)

README docs translated in other languages:

Setup

Add the library to your composer.json file in your project:

{
  "require": {
      "markrogoyski/itertools-php": "2.*"
  }
}

Use composer to install the library:

$ composer install

Composer will install IterTools inside your vendor folder. Then you can add the following to your .php files to use the library with Autoloading.

require_once __DIR__ . '/vendor/autoload.php';

Alternatively, use composer on the command line to require and install IterTools:

$ composer require markrogoyski/itertools-php:2.*

Minimum Requirements

  • PHP 8.2+
    • (For PHP 7.4–8.1, use v1.9)

Quick Reference

Loop Iteration Tools

Multi Iteration

Iterator Description Code Snippet
chain Chain multiple iterables together Multi::chain($list1, $list2)
zip Iterate multiple collections simultaneously until the shortest iterator completes Multi::zip($list1, $list2)
zipEqual Iterate multiple collections of equal length simultaneously, error if lengths not equal Multi::zipEqual($list1, $list2)
zipFilled Iterate multiple collections, using a filler value if lengths not equal Multi::zipFilled($default, $list1, $list2)
zipLongest Iterate multiple collections simultaneously until the longest iterator completes Multi::zipLongest($list1, $list2)

Single Iteration

Iterator Description Code Snippet
chunkwise Iterate by chunks Single::chunkwise($data, $chunkSize)
chunkwiseOverlap Iterate by overlapped chunks Single::chunkwiseOverlap($data, $chunkSize, $overlapSize)
compress Filter out elements not selected Single::compress($data, $selectors)
compressAssociative Filter out elements by keys not selected Single::compressAssociative($data, $selectorKeys)
dropWhile Drop elements while predicate is true Single::dropWhile($data, $predicate)
filter Filter for elements where predicate is true Single::filterTrue($data, $predicate)
filterTrue Filter for truthy elements Single::filterTrue($data)
filterFalse Filter for falsy elements Single::filterFalse($data)
filterKeys Filter for keys where predicate is true Single::filterKeys($data, $predicate)
flatMap Map function onto items and flatten result Single::flaMap($data, $mapper)
flatten Flatten multidimensional iterable Single::flatten($data, [$dimensions])
groupBy Group data by a common element Single::groupBy($data, $groupKeyFunction, [$itemKeyFunc])
limit Iterate up to a limit Single::limit($data, $limit)
map Map function onto each item Single::map($data, $function)
pairwise Iterate successive overlapping pairs Single::pairwise($data)
reindex Reindex keys of key-value iterable Single::reindex($data, $reindexer)
repeat Repeat an item a number of times Single::repeat($item, $repetitions)
reverse Iterate elements in reverse order Single::reverse($data)
skip Iterate after skipping elements Single::skip($data, $count, [$offset])
slice Extract a slice of the iterable Single::slice($data, [$start], [$count], [$step])
string Iterate the characters of a string Single::string($string)
takeWhile Iterate elements while predicate is true Single::takeWhile($data, $predicate)

Infinite Iteration

Iterator Description Code Snippet
count Count sequentially forever Infinite::count($start, $step)
cycle Cycle through a collection Infinite::cycle($collection)
repeat Repeat an item forever Infinite::repeat($item)

Random Iteration

Iterator Description Code Snippet
choice Random selections from list Random::choice($list, $repetitions)
coinFlip Random coin flips (0 or 1) Random::coinFlip($repetitions)
number Random numbers Random::number($min, $max, $repetitions)
percentage Random percentage between 0 and 1 Random::percentage($repetitions)
rockPaperScissors Random rock-paper-scissors hands Random::rockPaperScissors($repetitions)

Math Iteration

Iterator Description Code Snippet
frequencies Frequency distribution of data Math::frequencies($data, [$strict])
relativeFrequencies Relative frequency distribution of data Math::relativeFrequencies($data, [$strict])
runningAverage Running average accumulation Math::runningAverage($numbers, $initialValue)
runningDifference Running difference accumulation Math::runningDifference($numbers, $initialValue)
runningMax Running maximum accumulation Math::runningMax($numbers, $initialValue)
runningMin Running minimum accumulation Math::runningMin($numbers, $initialValue)
runningProduct Running product accumulation Math::runningProduct($numbers, $initialValue)
runningTotal Running total accumulation Math::runningTotal($numbers, $initialValue)

Set and multiset Iteration

Iterator Description Code Snippet
distinct Iterate only distinct items Set::distinct($data)
distinctBy Iterate only distinct items using custom comparator Set::distinct($data, $compareBy)
intersection Intersection of iterables Set::intersection(...$iterables)
intersectionCoercive Intersection with type coercion Set::intersectionCoercive(...$iterables)
partialIntersection Partial intersection of iterables Set::partialIntersection($minCount, ...$iterables)
partialIntersectionCoercive Partial intersection with type coercion Set::partialIntersectionCoercive($minCount, ...$iterables)
difference Difference of iterables Set::difference($a, ...$iterables)
differenceCoercive Difference with type coercion Set::differenceCoercive($a, ...$iterables)
symmetricDifference Symmetric difference of iterables Set::symmetricDifference(...$iterables)
symmetricDifferenceCoercive Symmetric difference with type coercion Set::symmetricDifferenceCoercive(...$iterables)
union Union of iterables Set::union(...$iterables)
unionCoercive Union with type coercion Set::unionCoercive(...$iterables)

Sort Iteration

Iterator Description Code Snippet
asort Iterate a sorted collection maintaining keys Sort::asort($data, [$comparator])
sort Iterate a sorted collection Sort::sort($data, [$comparator])

File Iteration

Iterator Description Code Snippet
readCsv Intersection a CSV file line by line File::readCsv($fileHandle)
readLines Iterate a file line by line File::readLines($fileHandle)

Transform Iteration

Iterator Description Code Snippet
tee Iterate duplicate iterators Transform::tee($data, $count)
toArray Transform iterable to an array Transform::toArray($data)
toAssociativeArray Transform iterable to an associative array Transform::toAssociativeArray($data, [$keyFunc], [$valueFunc])
toIterator Transform iterable to an iterator Transform::toIterator($data)

Summary

Summary Description Code Snippet
allMatch True if all items are true according to predicate Summary::allMatch($data, $predicate)
allUnique True if all items are unique Summary::allUnique($data, [$strict])
anyMatch True if any item is true according to predicate Summary::anyMatch($data, $predicate)
arePermutations True if iterables are permutations of each other Summary::arePermutations(...$iterables)
arePermutationsCoercive True if iterables are permutations of each other with type coercion Summary::arePermutationsCoercive(...$iterables)
exactlyN True if exactly n items are true according to predicate Summary::exactlyN($data, $n, $predicate)
isEmpty True if iterable has no items Summary::isEmpty($data)
isPartitioned True if partitioned with items true according to predicate before others Summary::isPartitioned($data, $predicate)
isSorted True if iterable sorted Summary::isSorted($data)
isReversed True if iterable reverse sorted Summary::isReversed($data)
noneMatch True if none of items true according to predicate Summary::noneMatch($data, $predicate)
same True if iterables are the same Summary::same(...$iterables)
sameCount True if iterables have the same lengths Summary::sameCount(...$iterables)

Reduce

Reducer Description Code Snippet
toAverage Mean average of elements Reduce::toAverage($numbers)
toCount Reduce to length of iterable Reduce::toCount($data)
toFirst Reduce to its first value Reduce::toFirst($data)
toFirstAndLast Reduce to its first and last values Reduce::toFirstAndLast($data)
toLast Reduce to its last value Reduce::toLast()
toMax Reduce to its largest element Reduce::toMax($numbers, [$compareBy])
toMin Reduce to its smallest element Reduce::toMin($numbers, [$compareBy])
toMinMax Reduce to array of upper and lower bounds Reduce::toMinMax($numbers, [$compareBy])
toNth Reduce to value at nth position Reduce::toNth($data, $position)
toProduct Reduce to the product of its elements Reduce::toProduct($numbers)
toRandomValue Reduce to random value from iterable Reduce::toRandomValue($data)
toRange Reduce to difference of max and min values Reduce::toRange($numbers)
toString Reduce to joined string Reduce::toString($data, [$separator], [$prefix], [$suffix])
toSum Reduce to the sum of its elements Reduce::toSum($numbers)
toValue Reduce to value using callable reducer Reduce::toValue($data, $reducer, $initialValue)

Stream Iteration Tools

Stream Sources

Source Description Code Snippet
of Create a stream from an iterable Stream::of($iterable)
ofCoinFlips Create a stream of random coin flips Stream::ofCoinFlips($repetitions)
ofCsvFile Create a stream from a CSV file Stream::ofCsvFile($fileHandle)
ofEmpty Create an empty stream Stream::ofEmpty()
ofFileLines Create a stream from lines of a file Stream::ofFileLines($fileHandle)
ofRandomChoice Create a stream of random selections Stream::ofRandomChoice($items, $repetitions)
ofRandomNumbers Create a stream of random numbers (integers) Stream::ofRandomNumbers($min, $max, $repetitions)
ofRandomPercentage Create a stream of random percentages between 0 and 1 Stream::ofRandomPercentage($repetitions)
ofRange Create a stream of a range of numbers Stream::ofRange($start, $end, $step)
ofRockPaperScissors Create a stream of rock-paper-scissors hands Stream::ofRockPaperScissors($repetitions)

Stream Operations

Operation Description Code Snippet
asort Sorts the iterable source maintaining keys $stream->asort([$comparator])
chainWith Chain iterable source withs given iterables together into a single iteration $stream->chainWith(...$iterables)
compress Compress source by filtering out data not selected $stream->compress($selectors)
compressAssociative Compress source by filtering out keys not selected $stream->compressAssociative($selectorKeys)
chunkwise Iterate by chunks $stream->chunkwise($chunkSize)
chunkwiseOverlap Iterate by overlapped chunks $stream->chunkwiseOverlap($chunkSize, $overlap)
distinct Filter out elements: iterate only unique items $stream->distinct([$strict])
distinctBy Filter out elements: iterate only unique items using custom comparator $stream->distinct($compareBy)
dropWhile Drop elements from the iterable source while the predicate function is true $stream->dropWhile($predicate)
filter Filter for only elements where the predicate function is true $stream->filterTrue($predicate)
filterTrue Filter for only truthy elements $stream->filterTrue()
filterFalse Filter for only falsy elements $stream->filterFalse()
filterKeys Filter for keys where predicate function is true $stream->filterKeys($predicate)
flatMap Map function onto elements and flatten result $stream->flatMap($function)
flatten Flatten multidimensional stream $stream->flatten($dimensions)
frequencies Frequency distribution $stream->frequencies([$strict])
groupBy Group iterable source by a common data element $stream->groupBy($groupKeyFunction, [$itemKeyFunc])
infiniteCycle Cycle through the elements of iterable source sequentially forever $stream->infiniteCycle()
intersectionWith Intersect iterable source and given iterables $stream->intersectionWith(...$iterables)
intersectionCoerciveWith Intersect iterable source and given iterables with type coercion $stream->intersectionCoerciveWith(...$iterables)
limit Limit the stream's iteration $stream->limit($limit)
map Map function onto elements $stream->map($function)
pairwise Return pairs of elements from iterable source $stream->pairwise()
partialIntersectionWith Partially intersect iterable source and given iterables $stream->partialIntersectionWith( $minIntersectionCount, ...$iterables)
partialIntersectionCoerciveWith Partially intersect iterable source and given iterables with type coercion $stream->partialIntersectionCoerciveWith( $minIntersectionCount, ...$iterables)
reindex Reindex keys of key-value stream $stream->reindex($reindexer)
relativeFrequencies Relative frequency distribution $stream->relativeFrequencies([$strict])
reverse Reverse elements of the stream $stream->reverse()
runningAverage Accumulate the running average (mean) over iterable source $stream->runningAverage($initialValue)
runningDifference Accumulate the running difference over iterable source $stream->runningDifference($initialValue)
runningMax Accumulate the running max over iterable source $stream->runningMax($initialValue)
runningMin Accumulate the running min over iterable source $stream->runningMin($initialValue)
runningProduct Accumulate the running product over iterable source $stream->runningProduct($initialValue)
runningTotal Accumulate the running total over iterable source $stream->runningTotal($initialValue)
skip Skip some elements of the stream $stream->skip($count, [$offset])
slice Extract a slice of the stream $stream->slice([$start], [$count], [$step])
sort Sorts the stream $stream->sort([$comparator])
differenceWith Difference of iterable source and given iterables $stream->differenceWith(...$iterables)
differenceCoerciveWith Difference of iterable source and given iterables with type coercion $stream->differenceCoerciveWith(...$iterables)
symmetricDifferenceWith Symmetric difference of iterable source and given iterables $stream->symmetricDifferenceWith(...$iterables)
symmetricDifferenceCoerciveWith Symmetric difference of iterable source and given iterables with type coercion $stream->symmetricDifferenceCoerciveWith(...$iterables)
takeWhile Return elements from the iterable source as long as the predicate is true $stream->takeWhile($predicate)
unionWith Union of stream with iterables $stream->unionWith(...$iterables)
unionCoerciveWith Union of stream with iterables with type coercion $stream->unionCoerciveWith(...$iterables)
zipWith Iterate iterable source with another iterable collection simultaneously $stream->zipWith(...$iterables)
zipEqualWith Iterate iterable source with another iterable collection of equal lengths simultaneously $stream->zipEqualWith(...$iterables)
zipFilledWith Iterate iterable source with another iterable collection using default filler $stream->zipFilledWith($default, ...$iterables)
zipLongestWith Iterate iterable source with another iterable collection simultaneously $stream->zipLongestWith(...$iterables)

Stream Terminal Operations

Summary Terminal Operations
Terminal Operation Description Code Snippet
allMatch Returns true if all items in stream match predicate $stream->allMatch($predicate)
allUnique Returns true if all items in stream are unique $stream->allUnique([$strict]])
anyMatch Returns true if any item in stream matches predicate $stream->anyMatch($predicate)
arePermutationsWith Returns true if all iterables permutations of stream $stream->arePermutationsWith(...$iterables)
arePermutationsCoerciveWith Returns true if all iterables permutations of stream with type coercion $stream->arePermutationsCoerciveWith(...$iterables)
exactlyN Returns true if exactly n items are true according to predicate $stream->exactlyN($n, $predicate)
isEmpty Returns true if stream has no items $stream::isEmpty()
isPartitioned Returns true if partitioned with items true according to predicate before others $stream::isPartitioned($predicate)
isSorted Returns true if stream is sorted in ascending order $stream->isSorted()
isReversed Returns true if stream is sorted in reverse descending order $stream->isReversed()
noneMatch Returns true if none of the items in stream match predicate $stream->noneMatch($predicate)
sameWith Returns true if stream and all given collections are the same $stream->sameWith(...$iterables)
sameCountWith Returns true if stream and all given collections have the same lengths $stream->sameCountWith(...$iterables)
Reduction Terminal Operations
Terminal Operation Description Code Snippet
toAverage Reduces stream to the mean average of its items $stream->toAverage()
toCount Reduces stream to its length $stream->toCount()
toFirst Reduces stream to its first value $stream->toFirst()
toFirstAndLast Reduces stream to its first and last values $stream->toFirstAndLast()
toLast Reduces stream to its last value $stream->toLast()
toMax Reduces stream to its max value $stream->toMax([$compareBy])
toMin Reduces stream to its min value $stream->toMin([$compareBy])
toMinMax Reduces stream to array of upper and lower bounds $stream->toMinMax([$compareBy])
toNth Reduces stream to value at nth position $stream->toNth($position)
toProduct Reduces stream to the product of its items $stream->toProduct()
toString Reduces stream to joined string $stream->toString([$separator], [$prefix], [$suffix])
toSum Reduces stream to the sum of its items $stream->toSum()
toRandomValue Reduces stream to random value within it $stream->toRandomValue()
toRange Reduces stream to difference of max and min values $stream->toRange()
toValue Reduces stream like array_reduce() function $stream->toValue($reducer, $initialValue)
Transformation Terminal Operations
Terminal Operation Description Code Snippet
toArray Returns array of stream elements $stream->toArray()
toAssociativeArray Returns key-value map of stream elements $stream->toAssociativeArray($keyFunc, $valueFunc)
tee Returns array of multiple identical Streams $stream->tee($count)
Side Effect Terminal Operations
Terminal Operation Description Code Snippet
callForEach Perform action via function on each item $stream->callForEach($function)
print print each item in the stream $stream->print([$separator], [$prefix], [$suffix])
printLn print each item on a new line $stream->printLn()
toCsvFile Write the contents of the stream to a CSV file $stream->toCsvFile($fileHandle, [$headers])
toFile Write the contents of the stream to a file $stream->toFile($fileHandle)

Stream Debug Operations

Debug Operation Description Code Snippet
peek Peek at each element between stream operations $stream->peek($peekFunc)
peekStream Peek at the entire stream between operations $stream->peekStream($peekFunc)
peekPrint Peek at each element by printing between operations $stream->peekPrint()
peekPrintR Peek at each element by doing print-r between operations $stream->peekPrintR()
printR print_r each item $stream->printR()
varDump var_dump each item $stream->varDump()

Documentation

Full documentation with detailed descriptions, signatures, and code examples for each function.

Loop Iteration

Summarize and Reduce

  • Summary — AllMatch, AnyMatch, IsEmpty, IsSorted, and more
  • Reduce — ToAverage, ToSum, ToMin, ToMax, ToString, and more

Stream

  • Stream — Sources, operations, terminal operations, and debug tools

Usage

All functions work on iterable collections:

  • array (type)
  • Generator (type)
  • Iterator (interface)
  • Traversable (interface)

Composition

IterTools can be combined to create new iterable compositions.

Zip Strings

use IterTools\Multi;
use IterTools\Single;

$letters = 'ABCDEFGHI';
$numbers = '123456789';

foreach (Multi::zip(Single::string($letters), Single::string($numbers)) as [$letter, $number]) {
     $battleshipMove = new BattleshipMove($letter, $number)
}
// A1, B2, C3

Chain Strings

use IterTools\Multi;
use IterTools\Single;

$letters = 'abc';
$numbers = '123';

foreach (Multi::chain(Single::string($letters), Single::string($numbers)) as $character) {
    print($character);
}
// a, b, c, 1, 2, 3

Strict and Coercive Types

When there is an option, the default will do strict type comparisons:

  • scalars: compares strictly by type
  • objects: always treats different instances as not equal to each other
  • arrays: compares serialized

When type coercion (non-strict types) is available and enabled via optional flag:

  • scalars: compares by value via type juggling
  • objects: compares serialized
  • arrays: compares serialized

Standards

IterTools PHP conforms to the following standards:

License

IterTools PHP is licensed under the MIT License.

Similar Libraries in Other Languages

IterTools functionality is not limited to PHP and Python. Other languages have similar libraries. Familiar functionality is available when working in other languages.