A simple newbie question (arrays and strings)

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

string = Dir.entries(".")
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

···

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!

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!

···

On May 25, 3:17 pm, koichirose <k...@ff.it> wrote:

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

* 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

* 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

I think you mean downcase, not lower.

Stefano

···

On Monday 26 May 2008, Simon Krahnke wrote:

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

Stefano Crocco wrote:

I think you mean downcase, not lower.

Yes, .downcase, confirmed

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 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

koichirose wrote:

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

That error message means you're trying to call the capitalize method on
something that doesn't exist. I.e. xxx.capitalise where xxx evaluates to
nil. The class NilClass doesn't have a capitalize method. Your problem
is with xxx; trying "p"-ing it.

···

--
Posted via http://www.ruby-forum.com/\.

Dave Bass wrote:

That error message means you're trying to call the capitalize method on something that doesn't exist. I.e. xxx.capitalise where xxx evaluates to nil. The class NilClass doesn't have a capitalize method. Your problem is with xxx; trying "p"-ing it.

Ok, but those 2 lines are the same, except that with list2 I take the part after ' - '.
If I do:

#~ j=0
#~ for i in list2
#~ puts list2[j]
#~ j +=1
#~ end

it works. Why are list and list2 behaving differently?

You have entries that either have no dash "-", or have one but nothing
after. You can NilClass#puts, but not just any method on it, such as
#capitalize. If you don't need them (like, for example, counting
purposes), remove your nils out of the array list with #compact.
Example in irb...

[1, nil, 2].compact
=> [1, 2]

Todd

···

On Tue, May 27, 2008 at 12:14 PM, koichirose <koi@ff.it> wrote:

Dave Bass wrote:
Ok, but those 2 lines are the same, except that with list2 I take the part
after ' - '.
If I do:

#~ j=0
#~ for i in list2
#~ puts list2[j]
#~ j +=1
#~ end