[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Array.which_long? ( I coded an extension for Array

Chris Carter

4/29/2007 2:11:00 PM

On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:
> Hi, I'm CFC
> I'm new at here.
> Nice to meet you:)
>
> I just coded an extension for Array.
> It will return the longest element of an array.
> Source:
>
> class Array
> def which_long?
> # Version 1.0
> # Coded by CFC < zusocfc @ gmail . com >
> # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
> # Usage:
> # ['a', 'ab', 'abc' 1234].which_long?
> # => 1234
> max, long, self_cpy = 0, "", []
> self.size.times{|i| self_cpy << self[i].to_s}
> self_cpy.each{|item| (max = item.size; long = item) if item.size > max }
> long
> end
> end
>
> Usage:
> puts [1, 23, '456'].which_long?
> => 456
>
> CFC --
>
How about:
class Array
def longest
self.map {|x| x.to_s }.sort_by {|x| x.size}[-1]
end
end

--
Chris Carter
concentrationstudios.com
brynmawrcs.com

15 Answers

Robert Klemme

4/30/2007 9:58:00 AM

0

On 29.04.2007 16:11, Chris Carter wrote:
> On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:
>> Hi, I'm CFC
>> I'm new at here.
>> Nice to meet you:)
>>
> > I just coded an extension for Array.
>> It will return the longest element of an array.
>> Source:
>>
>> class Array
>> def which_long?
>> # Version 1.0
>> # Coded by CFC < zusocfc @ gmail . com >
>> # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
>> # Usage:
>> # ['a', 'ab', 'abc' 1234].which_long?
>> # => 1234
>> max, long, self_cpy = 0, "", []
>> self.size.times{|i| self_cpy << self[i].to_s}
>> self_cpy.each{|item| (max = item.size; long = item) if item.size >
>> max }
>> long
>> end
>> end
>>
>> Usage:
>> puts [1, 23, '456'].which_long?
>> => 456
>>
>> CFC --
>>
> How about:
> class Array
> def longest
> self.map {|x| x.to_s }.sort_by {|x| x.size}[-1]
> end
> end

Thank you for leaving the #inject solutions to me. :-)

irb(main):001:0> %w{a ab abc 123 34}.inject{|a,b| a.size > b.size ? a : b}
=> "123"
irb(main):002:0> %w{a ab abc 123 34}.inject{|a,b| a.size >= b.size ? a : b}
=> "abc"

Kind regards

robert

Robert Dober

4/30/2007 10:40:00 AM

0

On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> On 29.04.2007 16:11, Chris Carter wrote:
> > On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:
> >> Hi, I'm CFC
> >> I'm new at here.
> >> Nice to meet you:)
> >>
> > > I just coded an extension for Array.
> >> It will return the longest element of an array.
> >> Source:
> >>
> >> class Array
> >> def which_long?
> >> # Version 1.0
> >> # Coded by CFC < zusocfc @ gmail . com >
> >> # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
> >> # Usage:
> >> # ['a', 'ab', 'abc' 1234].which_long?
> >> # => 1234
> >> max, long, self_cpy = 0, "", []
> >> self.size.times{|i| self_cpy << self[i].to_s}
> >> self_cpy.each{|item| (max = item.size; long = item) if item.size >
> >> max }
> >> long
> >> end
> >> end
> >>
> >> Usage:
> >> puts [1, 23, '456'].which_long?
> >> => 456
> >>
> >> CFC --
> >>
> > How about:
> > class Array
> > def longest
> > self.map {|x| x.to_s }.sort_by {|x| x.size}[-1]
> > end
> > end
>
> Thank you for leaving the #inject solutions to me. :-)
Are you kidding I posted an inject solution 19h ago ;)

But it was to return an array of all longest elements, I guess you can
maybe refine it, it seems clumsy, so I repost it just if you have some
time to play ;)

def longest
inject([]){ |s, e|
if s.empty? || s.first.size < e.to_s.size then [e]
elsif s.first.size == e.to_s.size then s << e
else s
end
}
end
>
> irb(main):001:0> %w{a ab abc 123 34}.inject{|a,b| a.size > b.size ? a : b}
> => "123"
> irb(main):002:0> %w{a ab abc 123 34}.inject{|a,b| a.size >= b.size ? a : b}

You get full credits for this anyway it is really beautiful, can you
stop being so clever ;).

Cheers
Robert


--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Robert Klemme

4/30/2007 11:48:00 AM

0

On 30.04.2007 12:39, Robert Dober wrote:
> On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
>> On 29.04.2007 16:11, Chris Carter wrote:
>> > On 4/29/07, Billy Hsu <ruby.maillist@gmail.com> wrote:
>> >> Hi, I'm CFC
>> >> I'm new at here.
>> >> Nice to meet you:)
>> >>
>> > > I just coded an extension for Array.
>> >> It will return the longest element of an array.
>> >> Source:
>> >>
>> >> class Array
>> >> def which_long?
>> >> # Version 1.0
>> >> # Coded by CFC < zusocfc @ gmail . com >
>> >> # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
>> >> # Usage:
>> >> # ['a', 'ab', 'abc' 1234].which_long?
>> >> # => 1234
>> >> max, long, self_cpy = 0, "", []
>> >> self.size.times{|i| self_cpy << self[i].to_s}
>> >> self_cpy.each{|item| (max = item.size; long = item) if item.size >
>> >> max }
>> >> long
>> >> end
>> >> end
>> >>
>> >> Usage:
>> >> puts [1, 23, '456'].which_long?
>> >> => 456
>> >>
>> >> CFC --
>> >>
>> > How about:
>> > class Array
>> > def longest
>> > self.map {|x| x.to_s }.sort_by {|x| x.size}[-1]
>> > end
>> > end
>>
>> Thank you for leaving the #inject solutions to me. :-)
> Are you kidding I posted an inject solution 19h ago ;)

I am sorry, I did not see it.

> But it was to return an array of all longest elements, I guess you can
> maybe refine it, it seems clumsy, so I repost it just if you have some
> time to play ;)
>
> def longest
> inject([]){ |s, e|
> if s.empty? || s.first.size < e.to_s.size then [e]
> elsif s.first.size == e.to_s.size then s << e
> else s
> end
> }
> end

Hm, I'd probably use case here. Let's see...

def longest
inject([]) do |lg, e|
case
when lg.empty?, lg.first.size == e.size
lg << e
when lg.first.size < e.size
[e]
else
lg
end
end
end

Alternative, but with higher memory consumption

def longest
lg = Hash.new {|h,k| h[k] = []}
each {|x| lg[x.size] << x}
lg.sort_by {|k,v| k}.last.pop
end

>> irb(main):001:0> %w{a ab abc 123 34}.inject{|a,b| a.size > b.size ? a
>> : b}
>> => "123"
>> irb(main):002:0> %w{a ab abc 123 34}.inject{|a,b| a.size >= b.size ? a
>> : b}
>
> You get full credits for this anyway it is really beautiful, can you
> stop being so clever ;).

Since I overlooked your posting I can't be so clever, can I? :-)

With #inject it's really special, it took me a while to pick it up and
now I can't stop using it. IIRC I even went to the exercise to
implement all methods in Enumerable by using #inject - maybe you can
find it in the archives. :-)

Kind regards

robert

Daniel Martin

4/30/2007 12:09:00 PM

0

"Robert Dober" <robert.dober@gmail.com> writes:

> But it was to return an array of all longest elements, I guess you can
> maybe refine it, it seems clumsy, so I repost it just if you have some
> time to play ;)
>
> def longest
> inject([]){ |s, e|
> if s.empty? || s.first.size < e.to_s.size then [e]
> elsif s.first.size == e.to_s.size then s << e
> else s
> end
> }
> end


That does seem clumsy. How about:

class Array
def longest
inject([0,[]]) { |(s,l),e|
if e.to_s.size == s then [s,l << e]
elsif e.to_s.size < s then [s,l]
else [e.to_s.size, [e]]
end
}[1]
end
end

Gotta love those destructuring block parameters.

--
s=%q( Daniel Martin -- martin@snowplow.org
puts "s=%q(#{s})",s.to_a[1] )
puts "s=%q(#{s})",s.to_a[1]

Robert Dober

4/30/2007 2:11:00 PM

0

On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:

>
> I am sorry, I did not see it.
I was just kidding Robert.
>
> > But it was to return an array of all longest elements, I guess you can
> > maybe refine it, it seems clumsy, so I repost it just if you have some
> > time to play ;)
> >
> > def longest
> > inject([]){ |s, e|
> > if s.empty? || s.first.size < e.to_s.size then [e]
> > elsif s.first.size == e.to_s.size then s << e
> > else s
> > end
> > }
> > end

>
> Hm, I'd probably use case here. Let's see...
>
> def longest
> inject([]) do |lg, e|
> case
> when lg.empty?, lg.first.size == e.size
> lg << e
> when lg.first.size < e.size
> [e]
> else
> lg
> end
> end
> end
better already, I am still looking for *the* solution
>
> Alternative, but with higher memory consumption
>
> def longest
> lg = Hash.new {|h,k| h[k] = []}
> each {|x| lg[x.size] << x}
> lg.sort_by {|k,v| k}.last.pop
> end
good idea but I wanted inject :)
> <snip>

Robert
--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Robert Klemme

4/30/2007 3:24:00 PM

0

On 30.04.2007 16:11, Robert Dober wrote:
> On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
>
>> I am sorry, I did not see it.
> I was just kidding Robert.

But I *did* overlook your posting. Honestly. :-)

>> > But it was to return an array of all longest elements, I guess you can
>> > maybe refine it, it seems clumsy, so I repost it just if you have some
>> > time to play ;)
>> >
>> > def longest
>> > inject([]){ |s, e|
>> > if s.empty? || s.first.size < e.to_s.size then [e]
>> > elsif s.first.size == e.to_s.size then s << e
>> > else s
>> > end
>> > }
>> > end
>
>>
>> Hm, I'd probably use case here. Let's see...
>>
>> def longest
>> inject([]) do |lg, e|
>> case
>> when lg.empty?, lg.first.size == e.size
>> lg << e
>> when lg.first.size < e.size
>> [e]
>> else
>> lg
>> end
>> end
>> end
> better already, I am still looking for *the* solution
>>
>> Alternative, but with higher memory consumption
>>
>> def longest
>> lg = Hash.new {|h,k| h[k] = []}
>> each {|x| lg[x.size] << x}
>> lg.sort_by {|k,v| k}.last.pop
>> end
> good idea but I wanted inject :)
>> <snip>

That's an easy transformation (left as exercise for the reader, bonus
points for a one liner). :-)

Cheers

robert

William James

4/30/2007 8:04:00 PM

0

On Apr 30, 6:47 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 30.04.2007 12:39, Robert Dober wrote:
>
>
>
> > On 4/30/07, Robert Klemme <shortcut...@googlemail.com> wrote:
> >> On 29.04.2007 16:11, Chris Carter wrote:
> >> > On 4/29/07, Billy Hsu <ruby.maill...@gmail.com> wrote:
> >> >> Hi, I'm CFC
> >> >> I'm new at here.
> >> >> Nice to meet you:)
>
> >> > > I just coded an extension for Array.
> >> >> It will return the longest element of an array.
> >> >> Source:
>
> >> >> class Array
> >> >> def which_long?
> >> >> # Version 1.0
> >> >> # Coded by CFC < zusocfc @ gmail . com >
> >> >> # PLEASE DO NOT REMOVE THE COMMENT OF THIS FUNCTION, THANKS A LOT.
> >> >> # Usage:
> >> >> # ['a', 'ab', 'abc' 1234].which_long?
> >> >> # => 1234
> >> >> max, long, self_cpy = 0, "", []
> >> >> self.size.times{|i| self_cpy << self[i].to_s}
> >> >> self_cpy.each{|item| (max = item.size; long = item) if item.size >
> >> >> max }
> >> >> long
> >> >> end
> >> >> end
>
> >> >> Usage:
> >> >> puts [1, 23, '456'].which_long?
> >> >> => 456
>
> >> >> CFC --
>
> >> > How about:
> >> > class Array
> >> > def longest
> >> > self.map {|x| x.to_s }.sort_by {|x| x.size}[-1]
> >> > end
> >> > end
>
> >> Thank you for leaving the #inject solutions to me. :-)
> > Are you kidding I posted an inject solution 19h ago ;)
>
> I am sorry, I did not see it.
>
> > But it was to return an array of all longest elements, I guess you can
> > maybe refine it, it seems clumsy, so I repost it just if you have some
> > time to play ;)
>
> > def longest
> > inject([]){ |s, e|
> > if s.empty? || s.first.size < e.to_s.size then [e]
> > elsif s.first.size == e.to_s.size then s << e
> > else s
> > end
> > }
> > end
>
> Hm, I'd probably use case here. Let's see...
>
> def longest
> inject([]) do |lg, e|
> case
> when lg.empty?, lg.first.size == e.size
> lg << e
> when lg.first.size < e.size
> [e]
> else
> lg
> end
> end
> end
>
> Alternative, but with higher memory consumption
>
> def longest
> lg = Hash.new {|h,k| h[k] = []}
> each {|x| lg[x.size] << x}
> lg.sort_by {|k,v| k}.last.pop
> end

def longest
max = map{|s| s.size}.max
select{|s| s.size == max}
end

Robert Dober

4/30/2007 10:03:00 PM

0

On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
<snip>
> >>
> >> def longest
> >> lg = Hash.new {|h,k| h[k] = []}
> >> each {|x| lg[x.size] << x}
> >> lg.sort_by {|k,v| k}.last.pop
> >> end
> > good idea but I wanted inject :)
> >> <snip>
>
> That's an easy transformation (left as exercise for the reader, bonus
> points for a one liner). :-)

inject( Hash.new{ |h,k| h[k]=[]} ){|h,e| h[e.size] << e}.sort_by....

as this is not readable anymore let me golf a little bit

inject([]){|a,e| a[e.size] = (a[e.size]||[])+[e];a}.last
hmm that is not too bad ;)

Robert


>
> Cheers
>
> robert
>
>


--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw

Robert Klemme

5/1/2007 7:10:00 AM

0

On 01.05.2007 00:03, Robert Dober wrote:
> On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> <snip>
>> >>
>> >> def longest
>> >> lg = Hash.new {|h,k| h[k] = []}
>> >> each {|x| lg[x.size] << x}
>> >> lg.sort_by {|k,v| k}.last.pop
>> >> end
>> > good idea but I wanted inject :)
>> >> <snip>
>>
>> That's an easy transformation (left as exercise for the reader, bonus
>> points for a one liner). :-)
>
> inject( Hash.new{ |h,k| h[k]=[]} ){|h,e| h[e.size] << e}.sort_by....
^^^^
The return from the block is missing. :-)

> as this is not readable anymore let me golf a little bit
>
> inject([]){|a,e| a[e.size] = (a[e.size]||[])+[e];a}.last
> hmm that is not too bad ;)

Couldn't you just use ||= here?

inject([]){|a,e|(a[e.size]||=[])<<e;a}.last

I like your idea to use the length as array index - that way no sorting
is needed. Brilliant!

Kind regards

robert

Robert Dober

5/1/2007 7:26:00 AM

0

On 5/1/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> On 01.05.2007 00:03, Robert Dober wrote:
> > On 4/30/07, Robert Klemme <shortcutter@googlemail.com> wrote:
> > <snip>
> >> >>
> >> >> def longest
> >> >> lg = Hash.new {|h,k| h[k] = []}
> >> >> each {|x| lg[x.size] << x}
> >> >> lg.sort_by {|k,v| k}.last.pop
> >> >> end
> >> > good idea but I wanted inject :)
> >> >> <snip>
> >>
> >> That's an easy transformation (left as exercise for the reader, bonus
> >> points for a one liner). :-)
> >
> > inject( Hash.new{ |h,k| h[k]=[]} ){|h,e| h[e.size] << e}.sort_by....
> ^^^^
> The return from the block is missing. :-)
Yeah I did not like this so I did not test it, I forgot the return of
the block in the solution below too, but I liked the solution and
therefore tested it....
>
> > as this is not readable anymore let me golf a little bit
> >
> > inject([]){|a,e| a[e.size] = (a[e.size]||[])+[e];a}.last
> > hmm that is not too bad ;)
>
> Couldn't you just use ||= here?
>
> inject([]){|a,e|(a[e.size]||=[])<<e;a}.last
Indeed, I guess I was very tired!!!
Now the solutions complexity and length just seems right.
Thanks for getting this right.
>
> I like your idea to use the length as array index - that way no sorting
> is needed. Brilliant!
Well that is grossly exaggerated, but thank you anyway, the idea was
yours of course I just used an Array instead of a Hash, that must be
my tiny Lua background.

Cheers
Robert

--
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw