I have been through the pickaxe book, looking at the array and enumerable
built-in class and module and can't find a way of achieving a map_if or
collect_if.
From pickaxe, collect "Returns a new array containing the results of running
block once for every element in enum". Of course map is an alias to collect.
There is find_all but it returns an array containing the elements of enum,
not the results of running the block, so I have written one.
Is there a better way that already exists?
thanks,
Bruce.
module Enumerable
# returns an array containing the results of running block once for every
element in enum, for which block
# is not false.
def map_if
rt, r = [], nil
self.each { |e| (r = yield(e)) and rt << r }
rt
end
alias :collect_if :map_if
irb(main):002:0* a = [ 1,2,3,4,5 ]
irb(main):003:0> b = a.select { |i|
irb(main):004:1* (i % 2 != 0) and (i * 10)
irb(main):005:1> }
=> [1, 3, 5]
···
On 4/12/06, Bruce Woodward <bruce.woodward@gmail.com> wrote:
Hi,
I have been through the pickaxe book, looking at the array and enumerable
built-in class and module and can't find a way of achieving a map_if or
collect_if.
From pickaxe, collect "Returns a new array containing the results of
running
block once for every element in enum". Of course map is an alias to
collect.
There is find_all but it returns an array containing the elements of enum,
not the results of running the block, so I have written one.
Is there a better way that already exists?
thanks,
Bruce.
module Enumerable
# returns an array containing the results of running block once for
every
element in enum, for which block
# is not false.
def map_if
rt, r = , nil
self.each { |e| (r = yield(e)) and rt << r }
rt
end
alias :collect_if :map_if
module Enumerable
def map_if( &block )
find_all(&block).map(&block)
end
end
this for sure is shorter, had no time to test performance though. ( I yield
twice, you yield only once, which might be costy!)
Cheers
Robert
···
On 4/13/06, Bruce Woodward <bruce.woodward@gmail.com> wrote:
Hi,
I have been through the pickaxe book, looking at the array and enumerable
built-in class and module and can't find a way of achieving a map_if or
collect_if.
From pickaxe, collect "Returns a new array containing the results of
running
block once for every element in enum". Of course map is an alias to
collect.
There is find_all but it returns an array containing the elements of enum,
not the results of running the block, so I have written one.
Is there a better way that already exists?
thanks,
Bruce.
module Enumerable
# returns an array containing the results of running block once for
every
element in enum, for which block
# is not false.
def map_if
rt, r = , nil
self.each { |e| (r = yield(e)) and rt << r }
rt
end
alias :collect_if :map_if
end
a = [ 1,2,3,4,5 ]
b = a.map_if { |i|
(i % 2 != 0) and (i * 10)
}
p b ## [10, 30, 50]
--
Deux choses sont infinies : l'univers et la bêtise humaine ; en ce qui
concerne l'univers, je n'en ai pas acquis la certitude absolue.
Thanks for your reply. I have been using inject but shyed away in this case
because for the 'real' code that I have been working on I am actually
already using an accumualtor.
module Enumerable
def map_if( &block )
find_all(&block).map(&block)
end
end
I particularly like the use of calling block twice. At first I thought that
this couldn't work but of course once the block has been successful for the
call to find_all, it must be successful for the call to map -- very nice.
I will file away the find_all {}.map {} idiom for future use but for this
case I will either use a manual accumulator or inject. The only reason is
performance and performance only matters in this case because the code is
likely to be get call many hundreds of times in a loop and I will be
impatiently waiting for it finish.
WRT to performance, not only is the block being called twice but an extra
array is being created and then freed. In the past I have had issues ruby
processes using a lot of memory and spending time with the garbage
collector. I don't want to start any kind of anti-ruby flame war here; Ruby
is my first choice. Manually stopping the GC at the top of the loop and
starting the GC at the bottom of the loop, solved the problem but I just
want to minimse memory use where I can, just for this code.
thanks again.
Bruce.
···
On 4/13/06, Robert Dober <robert.dober@gmail.com> wrote:
On 4/13/06, Bruce Woodward <bruce.woodward@gmail.com> wrote:
For integers gives you the value of the bit at the given index. All odd integers will have an LSB of 1
i.e.
1 -> 0b001
2 -> 0b010 # even
3 -> 0b011 #odd
4 -> 0b100 #even
5 -> 0b101 #odd
···
On Apr 14, 2006, at 11:07 AM, Stephan Mueller wrote:
I don't get it: why is i[0] == 1 returning true in case i is an integer
with an odd value?