Method: Array#zip

Defined in:
array.c

#zip(*other_arrays) ⇒ Object #zip(*other_arrays) {|sub_array| ... } ⇒ nil

With no block given, combines self with the collection of other_arrays; returns a new array of sub-arrays:

[0, 1].zip(['zero', 'one'], [:zero, :one])
# => [[0, "zero", :zero], [1, "one", :one]]

Returned:

  • The outer array is of size self.size.

  • Each sub-array is of size other_arrays.size + 1.

  • The nth sub-array contains (in order):

    • The nth element of self.

    • The nth element of each of the other arrays, as available.

Example:

a = [0, 1]
zipped = a.zip(['zero', 'one'], [:zero, :one])
# => [[0, "zero", :zero], [1, "one", :one]]
zipped.size       # => 2 # Same size as a.
zipped.first.size # => 3 # Size of other arrays plus 1.

When the other arrays are all the same size as self, the returned sub-arrays are a rearrangement containing exactly elements of all the arrays (including self), with no omissions or additions:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
 [:a1, :b1, :c1],
 [:a2, :b2, :c2],
 [:a3, :b3, :c3]]

When one of the other arrays is smaller than self, pads the corresponding sub-array with nil elements:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2]
c = [:c0, :c1]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
 [:a1, :b1, :c1],
 [:a2, :b2, nil],
 [:a3, nil, nil]]

When one of the other arrays is larger than self, ignores its trailing elements:

a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3, :b4]
c = [:c0, :c1, :c2, :c3, :c4, :c5]
d = a.zip(b, c)
pp d
# =>
[[:a0, :b0, :c0],
 [:a1, :b1, :c1],
 [:a2, :b2, :c2],
 [:a3, :b3, :c3]]

With a block given, calls the block with each of the other arrays; returns nil:

d = []
a = [:a0, :a1, :a2, :a3]
b = [:b0, :b1, :b2, :b3]
c = [:c0, :c1, :c2, :c3]
a.zip(b, c) {|sub_array| d.push(sub_array.reverse) } # => nil
pp d
# =>
[[:c0, :b0, :a0],
 [:c1, :b1, :a1],
 [:c2, :b2, :a2],
 [:c3, :b3, :a3]]

For an object in other_arrays that is not actually an array, forms the the “other array” as object.to_ary, if defined, or as object.each.to_a otherwise.

Related: see Methods for Converting.

Overloads:

  • #zip(*other_arrays) {|sub_array| ... } ⇒ nil

    Yields:

    • (sub_array)

    Returns:

    • (nil)


4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
# File 'array.c', line 4557

static VALUE
rb_ary_zip(int argc, VALUE *argv, VALUE ary)
{
    int i, j;
    long len = RARRAY_LEN(ary);
    VALUE result = Qnil;

    for (i=0; i<argc; i++) {
        argv[i] = take_items(argv[i], len);
    }

    if (rb_block_given_p()) {
        int arity = rb_block_arity();

        if (arity > 1) {
            VALUE work, *tmp;

            tmp = ALLOCV_N(VALUE, work, argc+1);

            for (i=0; i<RARRAY_LEN(ary); i++) {
                tmp[0] = RARRAY_AREF(ary, i);
                for (j=0; j<argc; j++) {
                    tmp[j+1] = rb_ary_elt(argv[j], i);
                }
                rb_yield_values2(argc+1, tmp);
            }

            if (work) ALLOCV_END(work);
        }
        else {
            for (i=0; i<RARRAY_LEN(ary); i++) {
                VALUE tmp = rb_ary_new2(argc+1);

                rb_ary_push(tmp, RARRAY_AREF(ary, i));
                for (j=0; j<argc; j++) {
                    rb_ary_push(tmp, rb_ary_elt(argv[j], i));
                }
                rb_yield(tmp);
            }
        }
    }
    else {
        result = rb_ary_new_capa(len);

        for (i=0; i<len; i++) {
            VALUE tmp = rb_ary_new_capa(argc+1);

            rb_ary_push(tmp, RARRAY_AREF(ary, i));
            for (j=0; j<argc; j++) {
                rb_ary_push(tmp, rb_ary_elt(argv[j], i));
            }
            rb_ary_push(result, tmp);
        }
    }

    return result;
}