Splitting each_cons?

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.

···

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

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.

···

On Sun, Apr 3, 2011 at 8:45 PM, Simon Harrison <simon@simonharrison.net> wrote:

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

one : vol1
one : vol2
three : vol3

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

···

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

#!/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

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

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.

···

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

For a while now I've been considering abandoning
learning programming as I find it hard going.

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.

···

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

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?

···

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

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.

···

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

I think the main thing that puts me off Python is having to import
everything:

import os
import re
import sys

and things don't always live where I think they should live. Zed Shaw
summed Python up here:

http://zedshaw.com/blog/2009-05-29.html

···

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

In ruby, the equivalent is require(). No difference.

···

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

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.

···

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

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

···

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

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.

···

On Sun, Apr 3, 2011 at 4:07 PM, Simon Harrison <simon@simonharrison.net>wrote:

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?

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

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?

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

Rob Biedenharn
Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/
rab@GaslightSoftware.com http://GaslightSoftware.com/

···

On Apr 3, 2011, at 5:07 PM, Simon Harrison wrote: