src/main/java/io/reactivex/Observable.java
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T, R> Observable<R> zip(Iterable<? extends ObservableSource<? extends T>> sources, Function<? super Object[], ? extends R> zipper) {
        ObjectHelper.requireNonNull(zipper, "zipper is null");
        ObjectHelper.requireNonNull(sources, "sources is null");
        return RxJavaPlugins.onAssembly(new ObservableZip<T, R>(null, sources, zipper, bufferSize(), false));
    }
@CheckReturnValue
    @SchedulerSupport(SchedulerSupport.NONE)
    public static <T, R> Observable<R> zip(Iterable<? extends ObservableSource<? extends T>> sources, Function<? super Object[], ? extends R> zipper) {
        ObjectHelper.requireNonNull(zipper, "zipper is null");
        ObjectHelper.requireNonNull(sources, "sources is null");
        return RxJavaPlugins.onAssembly(new ObservableZip<T, R>(null, sources, zipper, bufferSize(), false));
    }
Returns an Observable that emits the results of a specified combiner function applied to combinations of
items emitted, in sequence, by an Iterable of other ObservableSources.
<p>
{@code zip} applies this function in strict sequence, so the first item emitted by the new ObservableSource
will be the result of the function applied to the first item emitted by each of the source ObservableSources;
the second item emitted by the new ObservableSource will be the result of the function applied to the second
item emitted by each of those ObservableSources; and so forth.
<p>
The resulting {@code ObservableSource<R>} returned from {@code zip} will invoke {@code onNext} as many times as
the number of {@code onNext} invocations of the source ObservableSource that emits the fewest items.
<p>
The operator subscribes to its sources in order they are specified and completes eagerly if
one of the sources is shorter than the rest while disposing the other sources. Therefore, it
is possible those other sources will never be able to run to completion (and thus not calling
{@code doOnComplete()}). This can also happen if the sources are exactly the same length; if
source A completes and B has been consumed and is about to complete, the operator detects A won't
be sending further values and it will dispose B immediately. For example:
<pre><code>zip(Arrays.asList(range(1, 5).doOnComplete(action1), range(6, 5).doOnComplete(action2)), (a) -&gt; a)</code></pre>
{@code action1} will be called but {@code action2} won't.
<br>To work around this termination property,
use {@link #doOnDispose(Action)} as well or use {@code using()} to do cleanup in case of completion
or a dispose() call.
<p>
Note on method signature: since Java doesn't allow creating a generic array with {@code new T[]}, the
implementation of this operator has to create an {@code Object[]} instead. Unfortunately, a
{@code Function<Integer[], R>} passed to the method would trigger a {@code ClassCastException}.

<p>
<img width="640" height="380" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/zip.png" alt="">
<dl>
<dt><b>Scheduler:</b></dt>
<dd>{@code zip} does not operate by default on a particular {@link Scheduler}.</dd>
</dl>

@param <T> the common value type
@param <R> the zipped result type
@param sources
an Iterable of source ObservableSources
@param zipper
a function that, when applied to an item emitted by each of the source ObservableSources, results in
an item that will be emitted by the resulting ObservableSource
@return an Observable that emits the zipped results
@see <a href="http://reactivex.io/documentation/operators/zip.html">ReactiveX operators documentation: Zip</a>