Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New IterTools Functionality Discussion #39

Open
markrogoyski opened this issue Feb 16, 2023 · 11 comments
Open

New IterTools Functionality Discussion #39

markrogoyski opened this issue Feb 16, 2023 · 11 comments

Comments

@markrogoyski
Copy link
Owner

This thread is for discussion new functionality to implement in IterTools. Please reply with suggestions for new functionality.

Here are some of the functions I am considering implementing. Some are more useful than others.

Single Iteration

Skip

Skip the first n elements in the iterable.

public static function skip(iterable $data, int $n): \Generator

Shuffle

Shuffle the elements in the iterable.

public static function shuffle(iterable $data): \Generator

Note: More useful in a Stream than standalone function.

Filter RegEx

Filter for elements where the regular expression matches.

public static function filterRegEx(iterable $data, string $regex): \Generator

Permutations

All permutations of size $length.

public static function permutations(iterable $data, int $length) \Generator

Combinations

All combinations of size $length.

public static function combinations(iterable $data, int $length) \Generator

Combinations With Replacement

All combinations, with repeated elements, of size $length.

public static function combinationsWithReplacement(iterable $data, int $length) \Generator

Multi

Unzip

Reverse of zip.
Ex: ['a', 1], ['b', 2], ['c', 3] => ['a', 'b', 'c'], [1, 2, 3]

public static function unzip(...iterable $iterables): array

Reduce

To Random Value

Reduce the iterable to any random value in the iterable.

public static function toRandomValue(iterable $data): mixed

Note: More useful in a Stream than standalone function.

To Nth

Reduce the iterable to the value at the nth position.

public static function toNth(iterable $data): mixed

Note: More useful in a Stream than standalone function.

To Frequencies

Reduce the iterable to a frequency distribution showing how often each different value in the data occurs.

public static function toFrequencies(iterable $data): array

Note: MathPHP has this functionality. Maybe outside the scope for IterTools.

To Summary Stats

Reduce the iterable (of numbers) to a five-number summary.

public static function toSummaryStats(iterable $data): array

Note: MathPHP has this functionality. Maybe outside the scope for IterTools.

Summary

Not All Match

True if not all the elements are true according to the predicate.

public static function notAllMatch(iterable $data, callable $predicate): bool

Is Empty

True if the iterable is empty.

public static function isEmpty(iterable $data): bool

Note: More useful in a Stream than standalone function.

All Unique

True if all elements of the iterable are unique values.

public static function allUnique(iterable $data): bool

All Equal

True if all elements of the iterable are equal.

public static funcion allEqual(iterable $data): bool

Note: Consider maybe adding a strict parameter, or alternate method allSame.

Set

Union

Difference

CartesianProduct

Transform

Distribute

Distribute the elements of the iterable evenly into n smaller iterables.
Ex: [1, 2, 3, 4], 2 => [1, 3], [2, 4]

public static function distribute(iterable $data, int $n): array

Divide

Divide the elements of the iterable evenly into n smaller iterables, maintaining order.
Ex: [1, 2, 3, 4], 2 => [1, 2], [3, 4]

public static function divide(iterable $data, int $n): array

Stream

Peek

Peek at each element in between other Stream operations to do some action without modifying the stream. Useful for debugging purposes.

public function peek(callable $action): Stream

It might be useful to also add pre-built peaks:

  • peakPrint
  • peekPrintR

Example usage:

Stream::of($someData)
    ->map($someFunction)
    ->filter($anotherFunction)
    ->peakPrint()  // Added for debugging during development to see what is going on
    ->toAverage()

FYI: @Smoren.

@Smoren
Copy link
Contributor

Smoren commented Feb 16, 2023

Hi @markrogoyski,

Thank you very much for this topic! There are great ideas here and I'll start to implement some of them.

For the beginning I'll take peek(), if you don't mind (UPD: I've added PR with peek methods implementation: #40).

BTW, what about adding $offset param into skip() method to start skipping elements not from the beginning of an iterable?

public static function skip(iterable $data, int $count, int $offset = 0): \Generator

foreach (Single::skip([1, 2, 3, 4, 5, 6, 7], 3, 2) as $item) {
    // 1, 2, 6, 7
}

@markrogoyski
Copy link
Owner Author

Hi @Smoren,

For skip, I think as long as the offset is optional and defaults to 0 then that works.

@Smoren
Copy link
Contributor

Smoren commented Feb 17, 2023

Thanks, @markrogoyski, so the next method I'll implement is skip().

UPD: I've added PR #41 with functionality of skip().

@Smoren
Copy link
Contributor

Smoren commented Feb 17, 2023

Hi @markrogoyski,

What do you think about implementation of subslices()?

foreach (Single::subslices([1, 2, 3] as $slice) {
    // [1], [2], [3], [1, 2], [2, 3], [1, 2, 3]
}

BTW: I think it would be nice to have implemented method names strikethrough in this thread.

@Smoren
Copy link
Contributor

Smoren commented Feb 18, 2023

Hi @markrogoyski,

There is iter package.

What do you think about implementing some methods which are implemented in iter
but missing in IterTools PHP?

Here is a comparison:

IterTools PHP iter
Multi::chain chain
Multi::zip zip
Multi::zipEqual -
Multi::zipLongest -
- zipKeyValue
Single::chunkwise chunk
Single::chunkwiseOverlap -
- chunkWithKeys
Single::compress -
Single::compressAssociative -
- drop
Single::dropWhile dropWhile
- enumerate, toPairs (equivalents of each other, but not equivalents of Single::pairwise)
Single::filter filter
Single::filterTrue -
Single::filterFalse -
Single::filterKeys -
Single::flatMap flatMap
Single::flatten flatten
- flip
Single::groupBy -
- keys
Single::limit -
Single::map map
- mapKeys
- mapWithKeys
Single::pairwise -
- product
Single::reindex reindex
Single::repeat repeat
Single::reverse -
- recurse
Single::slice slice
Single::string split
- take
Single::takeWhile takeWhile
Infinite::count range
Infinite::cycle -
Infinite::repeat -
Random::choice -
Random::coinFlip -
Random::number -
Random::percentage -
Random::rockPaperScissors -
Math::runningAverage -
Math::runningDifference -
Math::runningMax -
Math::runningMin -
Math::runningProduct -
Math::runningTotal -
Set::distinct -
Set::intersection -
Set::intersectionCoercive -
Set::partialIntersection -
Set::partialIntersectionCoercive -
Set::symmetricDifference -
Set::symmetricDifferenceCoercive -
Sort::asort -
Sort::sort -
File::readCsv -
File::readLines -
- fromPairs
Transform::tee -
Transform::toArray toArray
Transform::toAssociativeArray toArrayWithKeys
Transform::toIterator toIter
Summary::allMatch all
Summary::anyMatch any
Summary::arePermutations -
Summary::arePermutationsCoercive -
Summary::exactlyN -
- isEmpty
- isIterable
Stream::callForEach apply
Summary::isPartitioned -
Summary::isSorted -
Summary::isReversed -
Summary::noneMatch -
Summary::same -
Summary::sameCount -
- reductions
- search
Reduce::toAverage -
Reduce::toCount count
Reduce::toFirst -
Reduce::toFirstAndLast -
Reduce::toLast -
Reduce::toMax -
Reduce::toMin -
Reduce::toMinMax -
Reduce::toProduct -
Reduce::toRange -
Reduce::toString join
Reduce::toSum -
Reduce::toValue reduce
- values

@Smoren
Copy link
Contributor

Smoren commented Feb 25, 2023

Hi @markrogoyski,

I've implemented some methods from this topic:

@Smoren
Copy link
Contributor

Smoren commented Mar 1, 2023

Hi @markrogoyski,

I've added and tested Summary::allUnique() method (#44).

@Smoren
Copy link
Contributor

Smoren commented Mar 2, 2023

Hi @markrogoyski,

I've added and tested Set::union() method (#45).

@Smoren
Copy link
Contributor

Smoren commented Mar 13, 2023

Hi @markrogoyski,

I've added and tested Reduce::toNth() method (#47).

@Smoren
Copy link
Contributor

Smoren commented Mar 20, 2023

Hi @markrogoyski,

What do you think about the implementation of zipFilled() function in IterTools PHP like I have done it in IterTools TS?

@markrogoyski
Copy link
Owner Author

Hi @Smoren,

I made a choice to not add a fill variable to zipLongest because it would have to be the first parameter, and even if you don't want a filler, you'd have to add that variable.

Interestingly, in PHP 8.1, you can have a named parameter after unpacking a variadic parameter, so I think you could do something like:

Multi::zipLongest($iter1, $iter2, fillValue: 'filler');

where the method signature is:

public function zipLongest(iterable ...$iterables, $fillValue = null);

Then it behaves and sort of looks like how you'd do it in Python.

Right now 7.4 is the minimum version. One option is to just wait a couple years and when I bump up the minimum version to something >= 8.1, then add it to zipLongest. Another option is to do like you suggest and implement a separate function like zipFilled.

Probably simplest to implement zipFilled as it keeps the interface to zipLongest simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants