All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.ericaro.neoitertools.Itertools Maven / Gradle / Ivy

The newest version!
package net.ericaro.neoitertools;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;

import net.ericaro.neoitertools.generators.ChainGenerator;
import net.ericaro.neoitertools.generators.CharSequenceGenerator;
import net.ericaro.neoitertools.generators.CycleGenerator;
import net.ericaro.neoitertools.generators.DropWhileGenerator;
import net.ericaro.neoitertools.generators.EmptyGenerator;
import net.ericaro.neoitertools.generators.EnumerateGenerator;
import net.ericaro.neoitertools.generators.FilterGenerator;
import net.ericaro.neoitertools.generators.GeneratorIterator;
import net.ericaro.neoitertools.generators.GenericArrayGenerator;
import net.ericaro.neoitertools.generators.GroupByGenerator;
import net.ericaro.neoitertools.generators.IteratorGenerator;
import net.ericaro.neoitertools.generators.MapGenerator;
import net.ericaro.neoitertools.generators.RangeGenerator;
import net.ericaro.neoitertools.generators.RepeatGenerator;
import net.ericaro.neoitertools.generators.YieldGenerator;
import net.ericaro.neoitertools.generators.SliceGenerator;
import net.ericaro.neoitertools.generators.TakeWhileGenerator;
import net.ericaro.neoitertools.generators.TeeGeneratorFactory;
import net.ericaro.neoitertools.generators.YieldThread;
import net.ericaro.neoitertools.generators.ZipGenerator;
import net.ericaro.neoitertools.generators.ZipPairGenerator;
import net.ericaro.neoitertools.generators.combinatorics.Combinatorics;
import net.ericaro.neoitertools.generators.primitives.BooleanGenerator;
import net.ericaro.neoitertools.generators.primitives.ByteGenerator;
import net.ericaro.neoitertools.generators.primitives.CharacterGenerator;
import net.ericaro.neoitertools.generators.primitives.DoubleGenerator;
import net.ericaro.neoitertools.generators.primitives.FloatGenerator;
import net.ericaro.neoitertools.generators.primitives.IntegerGenerator;
import net.ericaro.neoitertools.generators.primitives.LongGenerator;
import net.ericaro.neoitertools.generators.primitives.ShortGenerator;

/**
 * 

* This module implements a number of generator building blocks inspired by constructs from the Python programming languages. Each has been recast in a form * suitable for Java. *

*

* The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Standardization helps avoid the * readability and reliability problems which arise when many different individuals create their own slightly varying implementations, each with their own * quirks and naming conventions. *

*

* The tools are designed to combine readily with one another. This makes it easy to construct more specialized tools succinctly and efficiently in pure Java. *

* * @author eric * @see Itertools's wiki page * @see neoitertools site */ public class Itertools { /** *

* Return True if all elements of the generator are evaluated to true with the Predicate (or if the generator is empty). *

* * @param * type of generator elements * @param generator * @param predicate * @see Itertools's wiki page * @see neoitertools site * @return true|false */ public static boolean all(Generator generator, Lambda predicate) { try { while (predicate.map(generator.next())) { } return false; } catch (NoSuchElementException e) { return true; } } /** *

* Return True if any element of the generator is mapped to true. If the generator is empty, return False. *

* * @param generator * @param predicate * @return true|false * @see Itertools's wiki page * @see neoitertools site */ public static boolean any(Generator generator, Lambda predicate) { try { while (!predicate.map(generator.next())) { } return true; } catch (NoSuchElementException e) { return false; } } /** *

* Make an generator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are * exhausted. Used for treating consecutive sequences as a single sequence. *

*

* We do not use varargs due to an inner flaw in varargs that make them hard/impossible to combine with generics *

* * @param generators * a generator over generators * @return a new generator that chain together all the above generators * @see Itertools's wiki page * @see neoitertools site */ public static Generator chain(Generator> generators) { return new ChainGenerator(generators); } /** *

* Chain together two generators. *

* * @param generators * any generators * @see Itertools's wiki page * @see neoitertools site */ public static Generator chain(Generator... generators) { return chain(iter(generators)); } /** *

* Return r length subsequences of elements from the input generator. *

*

* Combinations are emitted in lexicographic sort order. So, if the input generator is sorted, the combination tuples will be produced in sorted order. *

*

* Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each * combination. *

* * @param generator * @param r * @return generator over combinations as list * @see Itertools's wiki page * @see neoitertools site */ public static Generator> combinations(Generator generator, int r) { List list = list(generator); return Combinatorics.applied(list, Combinatorics.combinations(list.size(), r)); } /** *

* Make a generator that returns all the consecutive integers starting with 0. *

* * @see Itertools#count(int) * @return a count generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator count() { return count(0); } /** *

* Make an generator that returns consecutive integers starting with n. *

* * @param n * the first integer returned by this generator * @return a count generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator count(final int n) { return new RangeGenerator(n, Integer.MAX_VALUE); } /** *

* Make an generator returning elements from the generator and saving a copy of each. When the generator is exhausted, return elements from the saved copy. * Repeats indefinitely. *

* * @param generator * the source generator * @return an generator returning elements from the generator over and over * again. * @see Itertools's wiki page * @see neoitertools site */ public static Generator cycle(Generator generator) { return new CycleGenerator(generator); } /** *

* Make an generator that drops elements from the generator as long as the predicate is true. Afterwards, returns every element. *

*

* Note, the generator does not produce any output until the predicate first becomes false, so it may have a lengthy start-up time. *

* * @param * @param generator * @param predicate * @return generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator dropwhile(Lambda predicate, Generator generator) { return new DropWhileGenerator(predicate, generator); } /** *

* Return an {@link Generator} of Index object. *

*

* The next() method of the generator returned by enumerate() returns an Index containing a count (from start which defaults to 0) and the corresponding * value obtained from iterating over generator. *

*

* enumerate() is useful for obtaining an indexed series: (0, seq[0]), (1, seq[1]), (2, seq[2]), .... For example: * *

	 * for (Index index : enumerate(seasons))
	 * 	System.out.println(index.i + " " + index.value);
	 * 
* * gives: * *
	 * 		0 Spring
	 * 		1 Summer
	 * 		2 Fall
	 * 		3 Winter
	 * 
* *

* * @param generator * the source generator to enumerate * @return a generator of index * @see Itertools's wiki page * @see neoitertools site */ public static Generator> enumerate(final Generator generator) { return new EnumerateGenerator(generator); } /** *

* Make an generator that filters elements from generator returning only those for which the predicate is True. *

* * @param predicate * @param generator * @return a filtered generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator filter(Lambda predicate, Generator generator) { return new FilterGenerator(predicate, generator); } /** *

* Make an generator that filters elements from generator returning only those for which the predicate is False. *

* * @param predicate * @param generator * @return a filtered generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator filterfalse(final Lambda predicate, final Generator generator) { return new FilterGenerator(predicate, generator, true); } /** *

* Make an generator that returns consecutive keys and groups from the source generator. *

*

* The key is a function computing a key value for each element. Generally, the generator needs to already be sorted on the same key function. *

*

* The operation of groupby() is similar to the uniq filter in Unix. It generates a break or new group every time the value of the key function changes * (which is why it is usually necessary to have sorted the data using the same key function). That behavior differs from SQL’s GROUP BY which aggregates * common elements regardless of their input order. The returned group is itself an generator that shares the underlying generator with groupby(). Because * the source is shared, when the groupby() object is advanced, the previous group is no longer visible. So, if that data is needed later, it should be * stored as a list. *

* * @param generator * the source generator * @param key * the key mapper * @return an generator that returns consecutive keys and groups from the * source generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator>> groupby(Generator generator, Lambda key) { return new GroupByGenerator(generator, key); } /** Return the identity Lambda function. * * @param any type */ public static Lambda identity() { return new Lambda() { public T map(T arg) { return arg; } }; } /** *

* Turn a {@link Generator} into an {@link Iterable}. *

* A much required function to use the java foreach statement. * *
	 * for (int i : in(range(12)))
	 * 	System.out.println(i);
	 * 
* * @param generator * the source generator * @return a iterable fully equivalent to the generator * @see Itertools's wiki page * @see neoitertools site */ public static Iterable in(final Generator generator) { return new Iterable() { public Iterator iterator() { return new GeneratorIterator(generator); } }; } /** * Turns any boolean[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(boolean[] array) { return new BooleanGenerator(array); } /** * Turns any byte[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(byte[] array) { return new ByteGenerator(array); } /** * Turns any char[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(char[] array) { return new CharacterGenerator(array); } /** * Turns a {@link CharSequence} into an {@link Generator} * * @param seq * any {@link CharSequence} * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(final CharSequence seq) { return new CharSequenceGenerator(seq); } /** * Turns any double[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(double[] array) { return new DoubleGenerator(array); } /** * Turns any float[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(float[] array) { return new FloatGenerator(array); } /** * Turns any int[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(int[] array) { return new IntegerGenerator(array); } /** * Turns any long[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(long[] array) { return new LongGenerator(array); } /** * Turns any short[] array into a generator * * @param array * @return a Generator over array * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(short[] array) { return new ShortGenerator(array); } /** * Turns any object array into an Generator * * @param t * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(final T[] t) { return new GenericArrayGenerator(t); } /** * Turn any {@link Iterable} into a {@link Generator} * * @param iterable * @return a generator over the iterable * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(Iterable iterable) { return iter(iterable.iterator()); } /** * Turn any {@link Iterator} into a {@link Generator} * * @param iterator * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(Iterator iterator) { return new IteratorGenerator(iterator); } /** * Turns a Yield generator into a standard Generator. * * @param yield a Yield generator statement * @see Itertools's wiki page * @see neoitertools site */ public static Generator iter(Yield yield) { return new YieldGenerator(yield); } /** * Creates a {@link List} from a {@link Generator} * * @param generator * @return a java modifiable List * @see Itertools's wiki page * @see neoitertools site */ public static List list(Generator generator) { List list = new LinkedList(); try { while (true) list.add(generator.next()); } catch (NoSuchElementException e) { } return list; } /** * Creates a list from a generator, of size max * * @param generator * @param max * maximum size of the list * @see Itertools's wiki page * @see neoitertools site */ public static List list(Generator generator, int max) { List list = new LinkedList(); try { int i = 0; while (i < max) { list.add(generator.next()); i++; } } catch (NoSuchElementException e) { } return list; } /** * Apply {@link Lambda} to every item of sequence and return a {@link Generator} of the results. * * @param mapper * @param sequence * @see Itertools's wiki page * @see neoitertools site */ public static Generator map(final Lambda mapper, final Generator sequence) { return new MapGenerator(mapper, sequence); } /** *

* Return successive full length permutations of elements in the generator. *

*

* Permutations are emitted in lexicographic sort order. So, if the input iterable is sorted, the permutation list will be produced in sorted order. *

*

* Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each * permutation. *

* * @param generator * @return generator of permuted list * @see Itertools's wiki page * @see neoitertools site */ public static Generator> permutations(Generator generator) { List list = list(generator); return Combinatorics.applied(list, Combinatorics.permutations(list.size())); } /** *

* Return successive r-length permutations of elements in the generator. *

*

* Permutations are emitted in lexicographic sort order. So, if the input iterable is sorted, the permutation list will be produced in sorted order. *

*

* Elements are treated as unique based on their position, not on their value. So if the input elements are unique, there will be no repeat values in each * permutation. *

* * @param generator * @param r * @return a generator of r-sized permutations * @see Itertools's wiki page * @see neoitertools site */ public static Generator> permutations(Generator generator, int r) { List list = list(generator); return Combinatorics.applied(list, Combinatorics.sublists(list.size(), r)); } /** * Cartesian product of input sequences. * * @param generators * a generator of Generators * @see Itertools's wiki page * @see neoitertools site */ public static Generator> product(Generator> generators) { return product(generators, 1); } /** *

* Cartesian product of input sequences. *

*

* repeat simulate the repetition of the input sequence. *

* * @param generators * a generator of Generators * @param repeat * @return a generator of cartesian product items * @see Itertools's wiki page * @see neoitertools site */ public static Generator> product(Generator> generators, int repeat) { if (repeat == 0) return new EmptyGenerator>(); List> list = new LinkedList>(); // store all values (required for a product for (Generator g : in(generators)) list.add(list(g)); // generate length array: length = len(lists) // [ len( lists[i%length]) for i in range( length ) ] // or for more fun // map( len, list*repeat ) // note that I don't use neoitertools to implement it to avoid bug // propagations // and that I should also provide a bunch of Lambda object for every // function in itertools (and more (like len ) int[] lengths = new int[list.size() * repeat]; for (int i = 0; i < lengths.length; i++) lengths[i] = list.get(i % list.size()).size(); return Combinatorics.selected(list, Combinatorics.product(lengths)); } /** * Equivalent to * *
	 * range(0, end, 1)
	 * 
* * @see Itertools#range(int, int, int) * @param end * @see Itertools's wiki page * @see neoitertools site */ public static Generator range(final int end) { return range(0, end, 1); } /** * equivalent to * *
	 * range(start, end, 1)
	 * 
* * @see Itertools#range(int, int, int) * @param start * @param end * @see Itertools's wiki page * @see neoitertools site */ public static Generator range(int start, int end) { return range(start, end, 1); } /** *

* This is a versatile function to create generator containing arithmetic progressions. *

*

* It is most often used in for loops. The full form returns an generator over Integers [start, start + step, start + 2 * step, ...]. *

    *
  • If step is positive, the last element is the largest start + i * step less than stop;
  • *
  • if step is negative, the last element is the smallest start + i * step greater than stop.
  • *
  • step must not be zero (or else InvalidParameterException is raised).
  • *

    *

    * Example: * *

    	 * range(0, 30, 5);
    	 * 
    * * gives * *
    	 * [0, 5, 10, 15, 20, 25]
    	 * 
    * *
    	 * range(0, 10, 3);
    	 * 
    * * gives * *
    	 * [0, 3, 6, 9];
    	 * 
    * *
    	 * range(0, -10, -1);
    	 * 
    * * gives * *
    	 * [0, -1, -2, -3, -4, -5, -6, -7, -8, -9];
    	 * 
    * *

    * * @param start * @param end * @param step * @see Itertools's wiki page * @see neoitertools site */ public static Generator range(final int start, final int end, final int step) throws InvalidParameterException { return new RangeGenerator(start, end, step); } /** * Equivalent to reduce(operator, generator, null); * * @param * @param operator * @param generator * @see Itertools's wiki page * @see neoitertools site */ public static T reduce(Operator operator, Generator generator) { return reduce(operator, generator, null); } /** *

    * Apply function of two arguments cumulatively to the items of generator, from left to right, so as to reduce the generator to a single value. *

    *

    * For example, * *

    	 * Operator<Integer> iadd = new Operator<Integer>() {
    	 * 	public Integer operate(Integer t1, Integer t2) {
    	 * 		return t1 + t2;
    	 * 	}
    	 * };
    	 * Integer res = reduce(iadd, range(1, 6), 0);
    	 * 
    * * calculates * *
    	 * ((((1 + 2) + 3) + 4) + 5)
    	 * 
    * *

    * The left argument, x, is the accumulated value and the right argument, y, * is the update value from the generator. If the initializer is not null, * it is placed before the items of the generator in the calculation, and * serves as a default when the iterable is empty. If initializer is null * and generator contains only one item, the first item is returned. * * @param operator * @param generator * @param initializer * @return all items reduced to a single one * @see Itertools's wiki page * @see neoitertools site */ public static T reduce(Operator operator, Generator generator, T initializer) { try { if (initializer == null) initializer = generator.next(); } catch (NoSuchElementException e) { return initializer; } try { while (true) initializer = operator.operate(initializer, generator.next()); } catch (NoSuchElementException e) { } return initializer; } /** *

    * Make an generator that returns object over and over again. *

    *

    * Runs indefinitely Used as argument to map() for invariant function parameters. Also used with zip() to create constant fields in a tuple record. *

    * * @param object * @return an generator that returns object over and over again. * @see Itertools's wiki page * @see neoitertools site */ public static Generator repeat(T object) { return new RepeatGenerator(object); } /** *

    * Make an generator that returns object times times. *

    *

    * Runs indefinitely unless the times argument is specified. Used as argument to imap() for invariant function parameters. Also used with izip() to create * constant fields in a tuple record. *

    * * @param object * @param times * number of times the object is returned * @return an generator that returns object over and over again. * @see Itertools's wiki page * @see neoitertools site */ public static Generator repeat(T object, int times) { return new RepeatGenerator(object, times); } /** *

    * Return a reverse generator. *

    *

    * The whole generator is stored, so be careful when used. *

    * * @param generator * the source generator * @return a generator that returns values in the reverse order * @see Itertools's wiki page * @see neoitertools site */ public static Generator reversed(Generator generator) { List list = list(generator); Collections.reverse(list); return iter(list); } /** * equivalent to {@link Itertools#slice}(0, stop, 1); * * @param generator * source generator * @param stop * last included index * @see Itertools's wiki page * @see neoitertools site */ public static Generator slice(final Generator generator, final int stop) { return new SliceGenerator(generator, 0, stop, 1); } /** * equivalent to {@link Itertools#slice}(start, stop, 1); * * @param generator * source generator * @param start * first included index * @param stop * last included index * @see Itertools's wiki page * @see neoitertools site */ public static Generator slice(final Generator generator, final int start, final int stop) { return slice(generator, start, stop, 1); } /** *

    * Make an generator that returns selected elements from the generator. *

    *

    * If start is non-zero, then elements from the generator are skipped until start is reached. Afterward, elements are returned consecutively unless step is * set higher than one which results in items being skipped. It stops at the specified position. slice() does not support negative values for start, stop, * or step. *

    * * @param generator * source generator * @param start * first included index * @param stop * last included index * @param step * @see Itertools's wiki page * @see neoitertools site */ public static Generator slice(final Generator generator, final int start, final int stop, final int step) { return new SliceGenerator(generator, start, stop, step); } /** * Returns a sorted Generator in natural ascending order of T. * * @param * @param generator * @see Itertools's wiki page * @see neoitertools site */ public static > Generator sorted(Generator generator) { List list = list(generator); Collections.sort(list); return iter(list); } /** *

    * Return a new sorted generator from the items in generator. *

    *

    * cmp specifies a custom Comparator of K. key specifies a {@link Lambda} that is used to extract a comparison key (K) from each generator * element. reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed. *

    * * @param * Type of items * @param * Type of the key used to filter * @param generator * source generator * @param key * key extraction function * @param reverse * if true the the comparison is used in reverse order * @see Itertools's wiki page * @see neoitertools site */ public static Generator sorted(Generator generator, final Comparator cmp, final Lambda key, final boolean reverse) { // maps T into (K,T) to perform the sort Lambda> valueToKeyValue = new Lambda>() { public Pair map(T arg) { return new Pair(key.map(arg), arg); } }; // Adversely maps (K,T) into T Lambda, T> keyValueToValue = new Lambda, T>() { public T map(Pair arg) { return arg.f1; } }; // use comparator of K to compare (K,T) Comparator> keyComparator = new Comparator>() { public int compare(Pair o1, Pair o2) { return (reverse ? -1 : 1) * cmp.compare(o1.f0, o2.f0); } }; List> list = list(map(valueToKeyValue, generator)); Collections.sort(list, keyComparator); return map(keyValueToValue, iter(list)); } /** * Return a new sorted generator from the items in generator. the comparator * is used to sort the generator. * * @param * @param generator * @see Itertools's wiki page * @see neoitertools site */ public static Generator sorted(Generator generator, Comparator cmp) { List list = list(generator); Collections.sort(list, cmp); return iter(list); } /** * Return a new sorted generator from the items in generator. the Key Lambda * is used to extract a key from T, and that key natural order is used to * sort the whole generator. * * @param * Type of items * @param * Type of the key used to filter * @param generator * source generator * @param key * key extraction function * @param reverse * if true the the comparison is used in reverse order * @see Itertools's wiki page * @see neoitertools site */ public static > Generator sorted(Generator generator, final Lambda key, final boolean reverse) { return sorted(generator, new Comparator() { public int compare(K o1, K o2) { return o1.compareTo(o2); } }, key, reverse); } /** * Turn any Generator of Character into a String * * @param chars * @see Itertools's wiki page * @see neoitertools site */ public static String string(Generator chars) { return stringBuilder(chars).toString(); } /** * Turn any Generator of Character into a StringBuilder * * @param chars * @see Itertools's wiki page * @see neoitertools site */ public static StringBuilder stringBuilder(Generator chars) { StringBuilder sb = new StringBuilder(); try { while (true) sb.append(chars.next().charValue()); } catch (NoSuchElementException e) { } return sb; } /** * Make an generator that returns elements from the generator as long as the * predicate is true. * * @param generator * the source generator * @param predicate * test function * @return an generator that returns elements from the generator as long as * the predicate is true. * @see Itertools's wiki page * @see neoitertools site */ public static Generator takewhile(final Generator generator, final Lambda predicate) { return new TakeWhileGenerator(predicate, generator); } /** * Return n independent generators from a single iterable. * * @param generator * the source generator * @param n * number of independent generators * @return an unmodifiable list of generators. * @see Itertools's wiki page * @see neoitertools site */ public static List> tee(Generator generator, int n) { // create the generator provider List> list = new ArrayList>(n); TeeGeneratorFactory factory = new TeeGeneratorFactory(generator); for (int i = 0; i < n; i++) list.add(factory.newInstance()); return list; } /** * Turns any Generator into a "tuple", here an unmodifiable {@link List} * * @param generator * @return a tuple extracted from a generator * @see Itertools's wiki page * @see neoitertools site */ public static List tuple(Generator generator) { return Collections.unmodifiableList(list(generator)); } /** * Causes the generate method to stop, and make the tvalue * returned by the associated next method. * * @param t * @see Yield protocol * @see Itertools's wiki page * @see neoitertools site */ public static R yield(T t) { YieldThread thread = (YieldThread) Thread.currentThread(); return thread.yield(t); } /** *

    * This function returns an {@link Generator} of tuple (unmodifiable List) , where the i-th couple contains the i-th element from each of the argument * generators. *

    *

    * The returned generator is truncated in length to the length of the shortest argument sequence. *

    *

    * Due to static typing of java, it is not possible to provide a generic length of generator and at the same time provide mixed-type tuples, therefore every * generator must be of type T. To have two-mixed type use {@link Itertools#zip(Generator, Generator)} *

    * * @param generators * @see Itertools's wiki page * @see neoitertools site */ public static Generator> zip(Generator> generators) { final List> generatorList = list(generators); return new ZipGenerator(generatorList); } /** *

    * This function returns an {@link Generator} of {@link Pair}s, where the i-th pair contains the i-th element from each of the argument generators. *

    *

    * The returned generator is truncated in length to the length of the shortest argument sequence. Due to static typing of java, it is not possible to * provide a generic length of generator and at the same time provide mixed-type tuples. *

    * * @param generator1 * @param generator2 * @see Itertools's wiki page * @see neoitertools site */ public static Generator> zip(final Generator generator1, final Generator generator2) { return new ZipPairGenerator(generator1, generator2); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy