Forum: Ruby can map/collect return fewer values than are found in the ta

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
6559f9b9607a89074ea5e238d31ffbc2?d=identicon&s=25 Kelly Dwight Felkins (Guest)
on 2006-02-09 02:18
(Received via mailing list)
Is there a way for collect to return fewer items than the enumerable the
collect is running on? It looks to me like
map/collect will return at least one value for each item in the array --
I've seen examples of how to return more items, but
not less.

Is there a way to do this more succinctly:

VOWELS = %w{a e i o u}
items = %w{ a b c d e f g h i}
new_items = []
items.each do |item|
  new_items << item unless VOWELS.include(item)
end
new_items

map/collect in ruby seems very similar to map in perl except that in
perl
the block can return zero or more elements. Is there an method in ruby
that
is similar to perl's map?

Thanks,

-Kelly
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2006-02-09 02:32
(Received via mailing list)
On Feb 8, 2006, at 8:18 PM, Kelly Dwight Felkins wrote:

> VOWELS = %w{a e i o u}
> ruby that
> is similar to perl's map?
>
> Thanks,
>
> -Kelly

new_items = items.reject { |item| VOWELS.include?(item) }

or

new_items = items.select { |item| true unless VOWELS.include?(item) }

or

new_items = items.inject([]) { |list, item| list << item unless
VOWELS.include?(item); list }
Cee0292fffa691f1fb320d5400200e99?d=identicon&s=25 Marcel Molina Jr. (Guest)
on 2006-02-09 02:38
(Received via mailing list)
On Thu, Feb 09, 2006 at 10:18:46AM +0900, Kelly Dwight Felkins wrote:
> new_items = []
> items.each do |item|
>   new_items << item unless VOWELS.include(item)
> end
> new_items
>
> map/collect in ruby seems very similar to map in perl except that in perl
> the block can return zero or more elements. Is there an method in ruby that
> is similar to perl's map?

Looks like you want Arry#select. In fact, take a look at the docs ;)

----------------------------------------------------------- Array#select
     array.select {|item| block } -> an_array
------------------------------------------------------------------------
     Invokes the block passing in successive elements from _array_,
     returning an array containing those elements for which the block
     returns a true value (equivalent to +Enumerable#select+).

        a = %w{ a b c d e f }
        a.select {|v| v =~ /[aeiou]/}   #=> ["a", "e"]

marcel
3ccecc71b9fb0a3d7f00a0bef6f0a63a?d=identicon&s=25 Kent Sibilev (Guest)
on 2006-02-09 02:38
(Received via mailing list)
items.inject([]){|a,i| a << i unless VOWELS.include?(i); a}

Kent.
430ea1cba106cc65b7687d66e9df4f06?d=identicon&s=25 David Vallner (Guest)
on 2006-02-09 03:10
(Received via mailing list)
The difference seems to be that Ruby's interpretation of map seems to be
stricter than Perl's, e.g. for one item in the original Array, there's
exactly one corresponding item in the result.

If you want a method with the behaviour similar to Perl's, you could do:

	class Array
		def pl_map(&block)
			map(&block).compact.flatten
		end
	end

	new_items = items.pl_map { | item | item if VOWELS.include(item) }

David Vallner

DÅ?a Å tvrtok 09 Február 2006 02:18 Kelly Dwight Felkins napísal:
6559f9b9607a89074ea5e238d31ffbc2?d=identicon&s=25 Kelly Felkins (Guest)
on 2006-02-09 06:13
(Received via mailing list)
Thanks much everyone. I think the combo of map with compact is what I
needed.

-Kelly
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 Robert Klemme (Guest)
on 2006-02-09 10:13
(Received via mailing list)
Logan Capaldo wrote:

> new_items = items.select { |item| true unless VOWELS.include?(item) }

new_items = items.select { |item| not VOWELS.include?(item) }

    robert
7fd7ef91196768cae4e7ca215c8a0a8f?d=identicon&s=25 Jeremy Henty (Guest)
on 2006-02-09 10:28
(Received via mailing list)
On 2006-02-09, Kelly Dwight Felkins <railsinator@gmail.com> wrote:

> Is there a way for collect to return fewer items than the enumerable
> the collect is running on?

Strictly speaking, no (AFAIK), but it's easy to fake it.  Use
Array#collect with a block that returns nil when you don't want an
element, then Array#compact the result.

Similarly, to get the effect of a block returning multiple values to
Array#collect, just have the block return an Array and then
Array#flatten the result.

Cheers,

Jeremy Henty
This topic is locked and can not be replied to.