Question - looking for library to use for query like code?


#1

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


#2

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


#3

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. :wink:

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


#4

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


#5

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


#6

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


#7

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


#8

Hope that helps.

Yes indeed, quite a lot. Thanks to both of you.