From: Brian Mitchell Date: 2006-04-21T02:29:52+09:00 Subject: Re: Converting IP range to array of IP's On 4/20/06, Kris wrote: > I'm looking to convert an IP string (ranges, subnet masks or wild-carded > IP's) in to an array of IP strings: > > eg. "192.168.1.1 - 192.168.1.5" => ["192.168.1.1", "192.168.1.2", > "192.168.1.3", "192.168.1.4", "192.168.1.5"] > > Before I embark on this, is there already a ruby class that does it or > some of this? Other's solutions should work great but just for fun and enlightenment I wrote my own little implementation of a simple list comprehension in Haskell and then ported it to Ruby. This simple piece of code allows you to expand more arbitrary ranges and might be good for more things than just IP addresses. # Condensed ruby version of this haskell code # # [[a,b,c,d] | a <- [192], b <- [168], c <- [0,1], d <- [1..10]] # # non-sugared notation: # [192] >>= \a -> # [168] >>= \b -> # [0,1] >>= \c -> # [1..10] >>= \d -> # return [a,b,c,d] class Array def expand(i = 0, *a) return [a] if i == size self[i].to_a.map {|x| expand(i+1, *(a + [x])) }.inject([]) {|m, a| m + a} end end [[192], [168], [0,1], (1..10)].expand #=> [[192, 168, 0, 1], [192, 168, 0, 2], [192, 168, 0, 3], [192, 168, 0, 4], [192, 168, 0, 5], [192, 168, 0, 6], [192, 168, 0, 7], [192, 168, 0, 8], [192, 168, 0, 9], [192, 168, 0, 10], [192, 168, 1, 1], [192, 168, 1, 2], [192, 168, 1, 3], [192, 168, 1, 4], [192, 168, 1, 5], [192, 168, 1, 6], [192, 168, 1, 7], [192, 168, 1, 8], [192, 168, 1, 9], [192, 168, 1, 10]] Kind of a fun thing to think about and try to wrap your head around sometime ;-)... maybe I should bundle a more complete monadic collections lib into a gem sometime. Brian.