From: "David A. Black" Date: 2010-10-11T19:15:00+09:00 Subject: Re: Testing for subarrays ---993115281-158264960-1286792098=:3161 Content-Type: MULTIPART/MIXED; BOUNDARY="-993115281-158264960-1286792098=:3161" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---993115281-158264960-1286792098=:3161 Content-Type: TEXT/PLAIN; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8BIT Hi -- On Mon, 11 Oct 2010, Jes�s Gabriel y Gal�n wrote: > On Mon, Oct 11, 2010 at 11:27 AM, Michel Demazure wrote: >> I want to check whether a given array contains a given subarray and >> return the corresponding range. >> Is there a builtin method ? If not, do you have better than this : >> >> class Array >> �def look_up(sub_array) >> � �len = sub_array.size >> � �self.each_cons(len).with_index do |cons, index| >> � � �return Range.new(index, index + len - 1) if cons == sub_array >> � �end >> � �nil >> �end >> end > > Not necessarily better: > > irb(main):001:0> a = [1,2,3,4,5,6,7,8] > => [1, 2, 3, 4, 5, 6, 7, 8] > irb(main):002:0> b = [4,5,6] > => [4, 5, 6] > irb(main):004:0> a.each_cons(b.size).to_a.index(b) > => 3 > irb(main):005:0> a.each_cons(b.size).to_a.index([5,1,2]) > => nil Here's another way that is more verbose but that doesn't create the whole array (which probably doesn't matter anyway, unless it's a huge array and you're cycle-shaving). I also prefer extending individual objects, rather than adding to Array. module SubArrayFinder def look_up(sub_array) sub_size = sub_array.size index = find_index.with_index do |e,i| self[i, sub_size] == sub_array end return(index..index+sub_size-1) if index end end David -- David A. Black, Senior Developer, Cyrus Innovation Inc. The Ruby training with Black/Brown/McAnally Compleat Philadelphia, PA, October 1-2, 2010 Rubyist http://www.compleatrubyist.com ---993115281-158264960-1286792098=:3161-- ---993115281-158264960-1286792098=:3161--