[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

learning the "Ruby way"

mark.wirdnam

11/20/2003 9:06:00 AM

**Hobby-programmer alarm**

Hello!
I am trying to learn Ruby, but with the goal of understanding new
elegant solutions, not to repeat the same messy solutions I usually
come up with.
Here is an example I would like to use to improve my understanding.
Any pointers would be great.

Problem:
I have a sorted list ('alfred', 'boris', 'bruce', 'claire', 'dean', 'donald')
and would like to generate or return ('-a-', 'alfred', '-b-', 'boris',
'bruce', '-c-', 'claire', '-d-', 'dean', 'donald').

Here's my solution:
lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']
prev = ''
newlst = Array.new
lst.each { |cur|
if cur[0..0] != prev
newlst.push("-#{cur[0..0]}-")
end
newlst.push(cur)
prev = cur[0..0] }

Is this the "Ruby way" of solving this problem? I doubt it, defining
"helper variables" like this is what had to be done in Basic, and my
solution doesn't demonstrate the high degree of readability Ruby is often
praised for.

Any useful suggestions for me? I'd be very grateful!
Mark
6 Answers

Dan Doel

11/20/2003 9:36:00 AM

0

I'm sure there are many ways of doing this, but here's one:

lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']

frob = lst.map do |val|
["-#{val[0..0]}-", val]
end.flatten.uniq

p frob

I'm not sure if #uniq is defined to leave the first occurrence and
delete all the rest or not,
but that's what it currently does, so it works.

- Dan


Robert Klemme

11/20/2003 10:34:00 AM

0


"Dan Doel" <djd15@po.cwru.edu> schrieb im Newsbeitrag
news:3FBC87DA.1090803@po.cwru.edu...
> I'm sure there are many ways of doing this, but here's one:
>
> lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']
>
> frob = lst.map do |val|
> ["-#{val[0..0]}-", val]
> end.flatten.uniq
>
> p frob
>
> I'm not sure if #uniq is defined to leave the first occurrence and
> delete all the rest or not,
> but that's what it currently does, so it works.

There must be an inject way of doing this...

lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']

frob = lst.inject( [[], nil] ) do |(res, key), word|
k = "-#{word[0].chr}-"
res << k unless k == key
res << word
[res, k]
end[0]


But this really cries for a Hash, because we have a typical key value
relationship here:

lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']

lst.inject( Hash.new {|h,k| h[k]=[]} ) {|res,w| res["-#{w[0].chr}-"] << w;
res}.sort.flatten

In fact, I'd just return the Hash. Then you have the appropriate data
structur. Simply omit ".sort.flatten" from the line above.

Regards

robert



Gavin Sinclair

11/20/2003 2:46:00 PM

0

On Thursday, November 20, 2003, 8:07:14 PM, Mark wrote:

> [...]

> Problem:
> I have a sorted list ('alfred', 'boris', 'bruce', 'claire', 'dean', 'donald')
> and would like to generate or return ('-a-', 'alfred', '-b-', 'boris',
> 'bruce', '-c-', 'claire', '-d-', 'dean', 'donald').

> Here's my solution:
> [...]

> Is this the "Ruby way" of solving this problem? I doubt it, defining
> "helper variables" like this is what had to be done in Basic, and my
> solution doesn't demonstrate the high degree of readability Ruby is often
> praised for.

> Any useful suggestions for me? I'd be very grateful!
> Mark


My first thought was to collect the values into a hash

{ 'a' => ['alfred'],
'd' => ['dean', 'donald'],
... }

then render that hash into the array that you want.

It's unlikely to be all that efficient, but both steps are very easy.

Cheers,
Gavin



Martin DeMello

11/20/2003 4:09:00 PM

0

Mark Wirdnam <mark.wirdnam@stud.unibas.ch> wrote:
>
> Problem:
> I have a sorted list ('alfred', 'boris', 'bruce', 'claire', 'dean', 'donald')
> and would like to generate or return ('-a-', 'alfred', '-b-', 'boris',
> 'bruce', '-c-', 'claire', '-d-', 'dean', 'donald').

One more way to do it...

require 'enum/cluster' # http://redshift.sourceforg...

lst = ['alfred', 'boris', 'bruce', 'claire', 'dean', 'donald']

a = ["--#{lst[0][0..0]}--"]
lst.each_cluster(2) {|i, j|
a << i
a << "--#{j[0..0]}--" if i[0] != j[0]
}

p a

martin

Simon Strandgaard

11/20/2003 4:25:00 PM

0

On Thu, 20 Nov 2003 01:06:25 -0800, Mark Wirdnam wrote:
> Is this the "Ruby way" of solving this problem? I doubt it, defining
> "helper variables" like this is what had to be done in Basic, and my
> solution doesn't demonstrate the high degree of readability Ruby is often
> praised for.
>
> Any useful suggestions for me? I'd be very grateful!
> Mark

How about this dirty solution ?


server> ruby a.rb
["-a-", "alfred", "-b-", "boris", "bruce", "-c-", "claire", "-d-", "dean", "donald"]
server> expand a.rb
names = %w(alfred boris bruce claire dean donald)
letters = names.map{|name| n=name[0..0]; [n, "-#{n}-"]}.uniq
p (letters + names.zip(names)).sort.transpose[1]
server>


--
Simon Strandgaard

mark.wirdnam

11/24/2003 8:21:00 AM

0

ok, I'm not quite there yet, but your helpful examples have given me
an idea how to go about things in Ruby. I think I see a main theme
being to use the power of the pre-defined methods of the
array/string/whatever.
Thanks for your help!

Mark