instance method
Enumerable#zip
[Elem2] (::_Each[Elem2] enum) -> ::Array[[ Elem, Elem2? ]]
(::_Each[untyped], *::_Each[untyped]) -> ::Array[::Array[untyped]]
[Elem2] (::_Each[Elem2]) { ([ Elem, Elem2? ]) -> void } -> nil
(::_Each[untyped], *::_Each[untyped]) { (::Array[untyped]) -> void } -> nil
zip(*other_enums) → array
zip(*other_enums) {|array| ... } → nil
enum.c
View on GitHub ↗
static VALUE
enum_zip(int argc, VALUE *argv, VALUE obj)
{
int i;
ID conv;
struct MEMO *memo;
VALUE result = Qnil;
VALUE args = rb_ary_new4(argc, argv);
int allary = TRUE;
argv = RARRAY_PTR(args);
for (i=0; i<argc; i++) {
VALUE ary = rb_check_array_type(argv[i]);
if (NIL_P(ary)) {
allary = FALSE;
break;
}
argv[i] = ary;
}
if (!allary) {
static const VALUE sym_each = STATIC_ID2SYM(id_each);
CONST_ID(conv, "to_enum");
for (i=0; i<argc; i++) {
if (!rb_respond_to(argv[i], id_each)) {
rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (must respond to :each)",
rb_obj_class(argv[i]));
}
argv[i] = rb_funcallv(argv[i], conv, 1, &sym_each);
}
}
if (!rb_block_given_p()) {
result = rb_ary_new();
}
/* TODO: use NODE_DOT2 as memo(v, v, -) */
memo = MEMO_NEW(result, args, 0);
rb_block_call(obj, id_each, 0, 0, allary ? zip_ary : zip_i, (VALUE)memo);
return result;
}
With no block given, returns a new array new_array of size self.size whose elements are arrays. Each nested array new_array[n] is of size other_enums.size+1, and contains:
-
The
n-th element of self. -
The
n-th element of each of theother_enums.
If all other_enums and self are the same size, all elements are included in the result, and there is no nil-filling:
Example
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] f = {foo: 0, bar: 1, baz: 2} g = {goo: 3, gar: 4, gaz: 5} h = {hoo: 6, har: 7, haz: 8} d = f.zip(g, h) d # => [ # [[:foo, 0], [:goo, 3], [:hoo, 6]], # [[:bar, 1], [:gar, 4], [:har, 7]], # [[:baz, 2], [:gaz, 5], [:haz, 8]] # ]
If any enumerable in other_enums is smaller than self, fills to self.size with nil:
Example
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2] c = [:c0, :c1] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
If any enumerable in other_enums is larger than self, its trailing elements are ignored:
Example
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3, :b4] c = [:c0, :c1, :c2, :c3, :c4, :c5] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil:
Example
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] a.zip(b, c) {|sub_array| p sub_array} # => nil
Output:
Example
[:a0, :b0, :c0] [:a1, :b1, :c1] [:a2, :b2, :c2] [:a3, :b3, :c3]