Splitting each_cons?

S

Simon Harrison

I'm not sure if each_cons can do what I'm trying to achieve:

one : vol1
one : vol2
three : vol3



irb(main):052:0> films
=> [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

irb(main):053:0> films.each_cons(1) { |f| print f, " " }
onevol1 onevol2 threevol3 => nil

irb(main):054:0> films.each_cons(1) { |f| print f, " ", "\n" }
onevol1
onevol2
threevol3
=> nil

irb(main):055:0> films.each_cons(1) { |f| puts f }
one
vol1
one
vol2
three
vol3
=> nil


Thanks for any help.
 
J

Jesús Gabriel y Galán

I'm not sure if each_cons can do what I'm trying to achieve:

one : vol1
one : vol2
three : vol3

To achieve this, you don't need each_cons, a simple each should suffice:

ruby-1.8.7-p334 :001 > films = [["one", "vol1"], ["one", "vol2"],
["three", "vol3"]]
=> [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]
ruby-1.8.7-p334 :002 > films.each {|film| puts "#{film.first} : #{film.last}"}
one : vol1
one : vol2
three : vol3

each_cons is typically used to traverse an array sliding several
elements at a time, for example:

ruby-1.8.7-p334 :003 > a = (1..20).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
ruby-1.8.7-p334 :004 > a.each_cons(3) {|x,y,z| p [x,y,z]}
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
[4, 5, 6]
[5, 6, 7]
[6, 7, 8]
[7, 8, 9]
[8, 9, 10]
[9, 10, 11]
[10, 11, 12]
[11, 12, 13]
[12, 13, 14]
[13, 14, 15]
[14, 15, 16]
[15, 16, 17]
[16, 17, 18]
[17, 18, 19]
[18, 19, 20]

Jesus.
 
S

Simon Harrison

Jesus: you have helped me once again. With your (and others)
assistance, I've now completed my first program that actually does
something useful. For a while now I've been considering abandoning
learning programming as I find it hard going. Thankfully, people such as
yourself spare the time to answer beginners questions and get us going
in the right direction.

I'm truly grateful to you, and everyone else here, who shares knowledge
with those seeking help. God bless you.

Here is the program (I know it needs tidying up :)


=====================


#!/opt/jruby/bin/jruby

require 'csv'

def load_xvid_file(path_to_csv)
@films = []
csv_data = CSV.read(path_to_csv)
csv_data.shift
csv_data.each do |row|
@films << [row[0], row[1]]
end
end

def search_for_film
print "Enter name of film to search for: "
film = gets.chomp.downcase
results = []
@films.each { |f| results << f unless f.grep(/#{film}/i).empty? }
if results.empty?
puts "Nothing found."
prompt
else
puts
puts "Results"
puts "======="
puts
results.each { |f| puts "#{f.first} : #{f.last}" }
puts
prompt
end
end

def prompt
print "Search again? (y or n) "
answer = gets.chomp.downcase

case answer
when /^y/
search_for_film
when /^n/
puts "Goodbye."
exit
else
prompt
end
end

load_xvid_file("/home/simon/Documents/CSV/XviD.csv")
search_for_film
 
7

7stud --

I would do it like this:


films = [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

films.each do |arr|
puts arr.join(' : ')
end

--output:--
one : vol1
one : vol2
three : vol3


And if you want to save the strings in a new_array--rather than print
them--you can use map():

films = [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

results = films.map do |arr|
arr.join(' : ')
end

p results

--output:--
["one : vol1", "one : vol2", "three : vol3"]


Array#join() and String#split() should be in every beginner's arsenal.
As for map(), it sends each element of the array to the block, and then
shoves the return value of the block into a new array. Here is a
simpler example:

films = [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

results = films.map do |arr|
"hello"
end

p results

--output:--
["hello", "hello", "hello"]

For each element of the array, the block returns one value, which is
stored in a new array.
 
B

Brian Candler

7stud -- wrote in post #990714:
I would do it like this:


films = [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

films.each do |arr|
puts arr.join(' : ')
end

--output:--
one : vol1
one : vol2
three : vol3

Or: since the elements you're yielding are themselves also arrays, ruby
can automatically assign them to individual variables if you wish (the
so-called "auto-splat" feature)

films = [["one", "vol1"], ["one", "vol2"], ["three", "vol3"]]

films.each do |label, volume|
puts "#{label}: #{volume}"
end
 
7

7stud --

For a while now I've been considering abandoning
Programming is a required skill. Stick with it. Next, you might try
reading the currently playing films off a website. As a first step, go
to www.google.com and grab the whole web page, and print out the first
200 characters.
 
S

Simon Harrison

Thanks guys. More options to try and remember! That's one of the things
that bugs me a bit about Ruby. TMTOWTDI.

each |film| film.first, film.last
each |film| film.join
each |label, volume| ...

My brain would like: if you have an array with subarrays acting as key,
value pairs, do this to access them. But, how am I to to decide which is
the "best" option from the above? I suppose it depends on the situation.
It becomes hard when every situation has multiple solutions and each
solution may effect what to do next; which has multipe solutions etc.

Still, I've tried Perl, Python, Lisp, C, C++, C#, Java, VB and probably
more, but Ruby seems to make sense more than all of these. At least I've
achieved something, eh?
 
7

7stud --

Jesus christ. Beginning ruby is a breeze compared to C++. And you
should see some perl in ruby. In any language, there are always
multiple ways to accomplish things. With experience you will hit on
the simplest way. In fact, this board is really a competition to post
the simplest way to do something.

Personally, I prefer python to all others.
 
S

Simon Harrison

Personally, I think that if Python had succeeded in it's aim, then I'd
be using it. The problem is that it has conceptions about where things
should be kept that only make sense to Python programmers.

In Ruby most file operations are in the File class. Those that aren't
should be found in the FileUtils class. Directories: try the Dir class.
That makes sense to me. Not scattered around Os, Sys, Shutils, Fnutils
and so on.

Python has a great philosophy but to a beginner can seem a bit of a
mess. No offence intended. That's just my view.
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

Thanks guys. More options to try and remember! That's one of the things
that bugs me a bit about Ruby. TMTOWTDI.

each |film| film.first, film.last
each |film| film.join
each |label, volume| ...

My brain would like: if you have an array with subarrays acting as key,
value pairs, do this to access them. But, how am I to to decide which is
the "best" option from the above? I suppose it depends on the situation.
It becomes hard when every situation has multiple solutions and each
solution may effect what to do next; which has multipe solutions etc.

Still, I've tried Perl, Python, Lisp, C, C++, C#, Java, VB and probably
more, but Ruby seems to make sense more than all of these. At least I've
achieved something, eh?
I would suggest the last one "each |label, volume|" as it is the most
explicit. If you look at that code, you have a much better idea what data
you are dealing with. If you want the label: just use label, the volume:
volume. In the first two, you will have to look around your code, or run
some experiment to see that film is a two element Array with the first
element being the label and the second being the volume, it is only a little
more obscure, but little things add up.
 
R

Rob Biedenharn

Thanks guys. More options to try and remember! That's one of the
things
that bugs me a bit about Ruby. TMTOWTDI.

each |film| film.first, film.last
each |film| film.join
each |label, volume| ...

My brain would like: if you have an array with subarrays acting as
key,
value pairs, do this to access them.

You should look at the Array#assoc method that lets you do exactly this.

http://www.ruby-doc.org/core/classes/Array.html#M000269

-Rob

P.S. Sorry if this was mentioned already, I know I'm jumping into the
middle of this conversation.
But, how am I to to decide which is
the "best" option from the above? I suppose it depends on the
situation.
It becomes hard when every situation has multiple solutions and each
solution may effect what to do next; which has multipe solutions etc.

Still, I've tried Perl, Python, Lisp, C, C++, C#, Java, VB and
probably
more, but Ruby seems to make sense more than all of these. At least
I've
achieved something, eh?

Rob Biedenharn
(e-mail address removed) http://AgileConsultingLLC.com/
(e-mail address removed) http://GaslightSoftware.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,740
Latest member
AdolphBig6

Latest Threads

Top