Forum: Ruby Question - looking for library to use for query like code?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Mmcolli00 M. (Guest)
on 2009-02-06 16:30
Can this be done with Ruby? (this may be a shot in the dark)

Say you have a text file with a lot of data and you want to group all of
your data by a specific value. Is there a way to code something in ruby
similar to a query that you would create using sql. Can this even be
done using Ruby? And if so, is there a library that you can refer me to?
If not, do you know any alternative ways? Thanks, MC

example of text:

auto, model
car, honda
truck, chevy
car, nissan
truck, toyota
truck, ford


how i'd like it to look:

car, honda, nissan,
truck, chevy, toyota, ford
Jean-Denis M. (Guest)
on 2009-02-06 17:01
(Received via mailing list)
Quoting Mmcolli00 Mom <removed_email_address@domain.invalid>:

> auto, model
> truck, chevy, toyota, ford
> --
> Posted via http://www.ruby-forum.com/.
>
>

Of course this is possible, and rather easy to write. Here are bits I
would use:

cars = hash.new

file = File.open("textfile.txt")
file.each {
  | line |
  wordarray = line.split(/,\s*/)

  cars[wordarray[0]] << wordarray[1]
}
file.close

file = File.open("outfile.txt", "w")
file << "cars, "
cars["cars"].each { |car| file << car << ", " }
file << "\n"
cars.["truck"].each { |car| file << car << ", " }
file << "\n"
file.close

This is not a complete, nor a general solution, but this should give you
an
idea.

Jean-Denis
James G. (Guest)
on 2009-02-06 17:08
(Received via mailing list)
On Feb 6, 2009, at 8:32 AM, Mmcolli00 Mom wrote:

> Can this be done with Ruby? (this may be a shot in the dark)

Anything can be done with Ruby.  ;)

> Say you have a text file with a lot of data and you want to group
> all of
> your data by a specific value. Is there a way to code something in
> ruby
> similar to a query that you would create using sql. Can this even be
> done using Ruby? And if so, is there a library that you can refer me
> to?
> If not, do you know any alternative ways? Thanks, MC

I'll show some pure Ruby code below that seems to do what you want,
but if you really want a query language you have several options.
Personally, I would use the Amalgalite gem to get SQLite.  You would
then just read the data and write it into a database.  You can then
query it in anyway you like.

> how i'd like it to look:
>
> car, honda, nissan,
> truck, chevy, toyota, ford

Here's some code that does that:

#!/usr/bin/env ruby -wKU

headers = DATA.gets.strip.split(/,\s*/)

related = { }
DATA.each do |row|
   fields = Hash[*headers.zip(row.strip.split(/,\s*/)).flatten]
   (related[fields["auto"]] ||= [ ]) << fields["model"]
end

related.keys.sort.each do |key|
   puts(([key] + related[key]).join(", "))
end

__END__
auto, model
car, honda
truck, chevy
car, nissan
truck, toyota
truck, ford

Hope it helps.

James Edward G. II
Jean-Denis M. (Guest)
on 2009-02-06 17:25
(Received via mailing list)
James' solution to the previous question being so much better than mine
(which I
did for my learning purposes), I dare asking about how to iterate over
two
arrays in parallel. I don't see a way to use the iteration methods, and
my
solution below doesn't feel idiomatic at all:

array1 = [1, 2, 3]
array2 = ["one", "two", "three"]
# note: both arrays are known to be the same size

(0..array1.size-1).each {
  | i |
  print "#{array2[i]} = #{array1[i]}\n"
}
Martin DeMello (Guest)
on 2009-02-06 17:32
(Received via mailing list)
On Fri, Feb 6, 2009 at 8:54 PM, Jean-Denis M. 
<removed_email_address@domain.invalid>
wrote:
> James' solution to the previous question being so much better than mine (which I
> did for my learning purposes), I dare asking about how to iterate over two
> arrays in parallel. I don't see a way to use the iteration methods, and my
> solution below doesn't feel idiomatic at all:
>
> array1 = [1, 2, 3]
> array2 = ["one", "two", "three"]
> # note: both arrays are known to be the same size

Use the block form of zip:

array1.zip(array2) {|i,j| print "#{i} = #{j}\n"}

martin
James G. (Guest)
on 2009-02-06 17:41
(Received via mailing list)
On Feb 6, 2009, at 9:24 AM, Jean-Denis M. wrote:

> James' solution to the previous question being so much better than
> mine (which I did for my learning purposes),

I think your solution was just fine.

>  print "#{array2[i]} = #{array1[i]}\n"
> }

Here's one way:

 >> array1 = (1..3).to_a
=> [1, 2, 3]
 >> array2 = %w[one two three]
=> ["one", "two", "three"]
 >> array1.zip(array2) { |num, word| puts "#{num} #{word}" }
1 one
2 two
3 three
=> nil

and another:

 >> require "generator"
=> true
 >> SyncEnumerator.new(array1, array2).each { |num, word| puts "#{num}
#{word}" }
1 one
2 two
3 three
=> #<SyncEnumerator:0x1115e58 @gens=[#<Generator:0x1115de0
@cont_endp=#<Continuation:0x11154bc>, cont_yieldnil, queue[],
block#<Proc:0x0111e15c@/usr/local/lib/ruby/1.8/generator.rb:71>,
cont_next#<Continuation:0x1115624, @index=3>, #<Generator:0x1115cc8
@cont_endp=#<Continuation:0x111546c>, cont_yieldnil, queue[],
block#<Proc:0x0111e15c@/usr/local/lib/ruby/1.8/generator.rb:71>,
cont_next#<Continuation:0x1115570, @index=3>]

Hope that helps.

James Edward G. II
unknown (Guest)
on 2009-02-06 18:10
(Received via mailing list)
On Feb 6, 8:32 am, Mmcolli00 Mom <removed_email_address@domain.invalid> wrote:
> auto, model
> --
> Posted viahttp://www.ruby-forum.com/.

data = Hash.new {|h,k| h[k] = []}

IO.foreach("myfile.txt"){|line|
  type, make = line.strip.split( / *, */ )
  data[ type ] << make
}

p data
Jean-Denis M. (Guest)
on 2009-02-06 18:46
(Received via mailing list)
> Hope that helps.

Yes indeed, quite a lot. Thanks to both of you.
This topic is locked and can not be replied to.