From: murphy Date: 2007-11-15T18:49:17+09:00 Subject: Re: Proposal: Array#walker Wolfgang N��dasi-Donner wrote: > I wanted to have a Method of class Array, which "walks" through an Array > object like "each" without using any index at all, and presents the left > and the right context of the actual element of the "each like" > processing inside the block. I know :) I wanted to propose a more general method that would still help you to simpify / speed up your code. there currently is no method to split an array into two with one call based on indices. even a method that splits an array into two at a given index seems to specialized for me. that's why split_at should work as the opposite of Array#slice/Array#[], which has well-known semantics. (a syntax like a]i[ would be funny, but please ignore it ^_^) I'm not sure about the name though..."at" sounds like it always takes an index. however, here's a version that does just that: VALUE rb_ary_split_at(VALUE ary, VALUE pos) { long index = NUM2LONG(pos); if (RARRAY_LEN(ary) == 0) { return rb_assoc_new(rb_ary_new2(0), rb_ary_new2(0)); } if (index < 0) { index += RARRAY_LEN(ary); } /* special cases */ if (index < 0) { return rb_assoc_new(rb_ary_new2(0), rb_ary_dup(ary)); } if (index >= RARRAY_LEN(ary)) { return rb_assoc_new(rb_ary_dup(ary), rb_ary_new2(0)); } return rb_assoc_new( rb_ary_subseq(ary, 0, index), rb_ary_subseq(ary, index + 1, RARRAY_LEN(ary) - (index + 1)) ); } irb(main):005:0> a = Array(1..10); a.each_with_index { |el,i| pre, post = a.split_at(i); p [pre, el, post] } [[], 1, [2, 3, 4, 5, 6, 7, 8, 9, 10]] [[1], 2, [3, 4, 5, 6, 7, 8, 9, 10]] [[1, 2], 3, [4, 5, 6, 7, 8, 9, 10]] [[1, 2, 3], 4, [5, 6, 7, 8, 9, 10]] [[1, 2, 3, 4], 5, [6, 7, 8, 9, 10]] [[1, 2, 3, 4, 5], 6, [7, 8, 9, 10]] [[1, 2, 3, 4, 5, 6], 7, [8, 9, 10]] [[1, 2, 3, 4, 5, 6, 7], 8, [9, 10]] [[1, 2, 3, 4, 5, 6, 7, 8], 9, [10]] [[1, 2, 3, 4, 5, 6, 7, 8, 9], 10, []] => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [murphy]