From: "Marshall T. Vandegrift" Date: 2006-09-14T06:22:52+09:00 Subject: Re: How to collect over two arrays then look back to one? Peter Booth writes: > I am reading Ruby for Rails and Ruby Cookbock and delighted by the > Array#find_all and Enumerable#collect methods. I'm wondering what the > idiomatic way to do the following is? Kind of. But first I'm going to re-arrange your email to answer more didactically. :-) > Can the block inside Enumerable#collect know it's position inside the > Enumerable? Enumerable::Enumerator -- require 'enumerator' -- can help you out with this. It lets you create an Enumerable object which can call any 'each'-like method of any other object. You can in turn call the 'collect' method of the Enumerator object. So: array.to_enum(:each_with_index).collect { |value, index| ... } (Using :each_with_index is a common enough case that Enumerator also adds #enum_with_index to Enumerable.) > Can one collect two parallel arrays? In several ways... The most basic is the Enumerable#zip method: (0..3).zip(('a'..'d')) # => [[0, "a"], [1, "b"], [2, "c"], [3, "d"]] It returns a new array mapping each element of the receiving Enumerable to the corresponding elements of the Enumerables passed as arguments. > Two parallel arrays A, B . For each element n of A for which f(An) is true, > is g(B[n-3:n+3]) true? Where B[n-3:n+3] refers to seven elements of B whose > position is centered over An' position. Enumerable#inject is the most idiomatic way to perform most Enumerable iteration not directly supported by other methods. If I understand you properly, in this case you probably want something like: a.enum_with_index.inject([]) do |result, (v, n)| result << (f(v) ? g(b[n-3..n+3]) : false) end Hope this helps! -Marshall