[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

A simple newbie question (arrays and strings

koichirose

5/25/2008 8:17:00 PM

Today I started programming in ruby.
Here's what I managed to do so far:

string = Dir.entries(".")
string.delete_at(0)
string.delete_at(0)

1. I get a list of files
2-3. I delete the first two elements ('.' and '..')

Now my files are all like "something - some other thing"
I want to split them:

string.each do |s|
puts s.split("-")[0]
end

So it outputs the "something" part in my filenames.
Now I'd like to remove duplicate entries (.uniq method right?).
Can it be done in a single line? If not, how do i get an array
containing only the "something" part to work on with .uniq?

I tried with some loops, to create a new array with the splitted string
in it, but my PHP approach doesn't work:
i = 0
for i in string
splitted[i] = i.split("-")[0]
i += 1
end

Thank you!
13 Answers

Stefano Crocco

5/25/2008 8:30:00 PM

0

On Sunday 25 May 2008, koichirose wrote:
> Today I started programming in ruby.
> Here's what I managed to do so far:
>
> string = Dir.entries(".")
> string.delete_at(0)
> string.delete_at(0)
>
> 1. I get a list of files
> 2-3. I delete the first two elements ('.' and '..')
>
> Now my files are all like "something - some other thing"
> I want to split them:
>
> string.each do |s|
> puts s.split("-")[0]
> end
>
> So it outputs the "something" part in my filenames.
> Now I'd like to remove duplicate entries (.uniq method right?).
> Can it be done in a single line? If not, how do i get an array
> containing only the "something" part to work on with .uniq?
>
> I tried with some loops, to create a new array with the splitted string
> in it, but my PHP approach doesn't work:
> i = 0
> for i in string
> splitted[i] = i.split("-")[0]
> i += 1
> end
>
> Thank you!

If I understand you correctly, this (untested) should do what you want:
Dir.entries('.')[2..-1].map{|f| f.split('-')[0]}.uniq

Dir.entries('.')[2..-1]

returns an array containing all the contents of the current directory except
the first two entries (actually, the [] method of an array, when called with a
range returns all the elements of the array from the first index to the last.
Since negative indexes count from right to left, with the rigthmost element
having index -1, here you get all the entries from 2 to the last). This avoids
the two calls to delete_at.

Then map is called on the array with the names of the files. Array#map passes
each element of the array to the block and returns an array containing the
values returned by the block for each element. In this case, each element is a
string of the form 'something-something_else'. The block splits the name of
the file on the '-' character, then takes (and implicitly returns) the first
half (thanks to the [0]). This means that map returns an array containing all
the first parts of the file names (the ones you want).

After that, we call uniq on the array, creating a new array without
duplicates.

I hope this helps

Stefano


yermej

5/25/2008 8:32:00 PM

0

On May 25, 3:17 pm, koichirose <k...@ff.it> wrote:
> Today I started programming in ruby.
> Here's what I managed to do so far:
>
> string = Dir.entries(".")
> string.delete_at(0)
> string.delete_at(0)
>
> 1. I get a list of files
> 2-3. I delete the first two elements ('.' and '..')
>
> Now my files are all like "something - some other thing"
> I want to split them:
>
> string.each do |s|
> puts s.split("-")[0]
> end
>
> So it outputs the "something" part in my filenames.
> Now I'd like to remove duplicate entries (.uniq method right?).
> Can it be done in a single line? If not, how do i get an array
> containing only the "something" part to work on with .uniq?
>
> I tried with some loops, to create a new array with the splitted string
> in it, but my PHP approach doesn't work:
> i = 0
> for i in string
> splitted[i] = i.split("-")[0]
> i += 1
> end
>
> Thank you!

One way would be to use Dir.glob:

unique_array = Dir.glob('*-*').map {|f| f.split('-')[0]}.uniq

Then you only get filenames that have - in them.

Or:

unique_array = Dir.entries('.')[2..-1].map {|f| f.split('-')[0]}.uniq

But starting from here:

> string = Dir.entries(".")
> string.delete_at(0)
> string.delete_at(0)
string.map! {|f| f.split('-')[0]}.uniq!

koichirose

5/25/2008 8:49:00 PM

0

Stefano Crocco wrote:
> If I understand you correctly, this (untested) should do what you want:
> Dir.entries('.')[2..-1].map{|f| f.split('-')[0]}.uniq

Hai capito bene :) Continuo in inglese che penso sia contro le regole
parlare in italiano ^^

>
> Dir.entries('.')[2..-1]
This avoids
> the two calls to delete_at.

Nice :)

> This means that map returns an array containing all
> the first parts of the file names (the ones you want).

Does map{} work as some sort of loop in which it executes the split
method on each element?

> I hope this helps

It works! I see that .uniq is case-sensitive (something else !=
something Else). Can I avoid that?
Grazie!

koichirose

5/25/2008 8:52:00 PM

0

yermej wrote:
> unique_array = Dir.entries('.')[2..-1].map {|f| f.split('-')[0]}.uniq
> string.map! {|f| f.split('-')[0]}.uniq!

What if I do:
Dir.entries('.')[2..-1].map! {|f| f.split('-')[0]}.uniq

with map! instead of map ?
I'd now have Dir.entries trimmed, splitted and "uniqed" ?
Thanks

Simon Krahnke

5/26/2008 7:02:00 AM

0

* koichirose <koi@ff.it> (22:51) schrieb:

> yermej wrote:
>> unique_array = Dir.entries('.')[2..-1].map {|f| f.split('-')[0]}.uniq
>> string.map! {|f| f.split('-')[0]}.uniq!
>
> What if I do:
> Dir.entries('.')[2..-1].map! {|f| f.split('-')[0]}.uniq
>
> with map! instead of map ?

map! changes the array it's called on. since that is a temporary array
returned by Dir.entries[2..-1] which is discarded after map! that won't
work.

mfg, simon .... l

Simon Krahnke

5/26/2008 7:03:00 AM

0

* koichirose <koi@ff.it> (22:48) schrieb:

> It works! I see that .uniq is case-sensitive (something else !=
> something Else). Can I avoid that?

Yes, just convert it to lower case before the uniq:

Dir.entries('.')[2..-1].map{|f| f.split('-')[0].lower}.uniq

mfg, simon .... l

Stefano Crocco

5/26/2008 7:39:00 AM

0

On Monday 26 May 2008, Simon Krahnke wrote:
> Dir.entries('.')[2..-1].map{|f| f.split('-')[0].lower}.uniq

I think you mean downcase, not lower.

Stefano


koichirose

5/26/2008 3:46:00 PM

0

Stefano Crocco wrote:
> I think you mean downcase, not lower.

Yes, .downcase, confirmed

koichirose

5/26/2008 3:47:00 PM

0

Simon Krahnke wrote:
> map! changes the array it's called on. since that is a temporary array
> returned by Dir.entries[2..-1] which is discarded after map! that won't
> work.

Right..Thank you!

koichirose

5/27/2008 11:11:00 AM

0

koichirose wrote:
> Yes, .downcase, confirmed

I have a problem, why does this work:
list = Dir.entries('.')[2..-1].map{|f| f.split(' - ')[0].capitalize}

And this doesn't?
list2 = Dir.entries('.')[2..-1].map{|f| f.split(' - ')[1].capitalize}

It returns: hello.rb:7: undefined method `capitalize' for nil:NilClass
(NoMethodError)
from hello.rb:7:in `map'

Thank you