Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Help with Multi Dimensional Array

Reply
Thread Tools

Help with Multi Dimensional Array

 
 
lionbarrage
Guest
Posts: n/a
 
      02-25-2009
I'm new to ruby and have been trying to figure out what I'm doing
wrong.

I'm completely stumped about how to merge two files together based on
whether they share the same key or not.

Example:

File 1
ALPHA|OMEGA|GAMMA
1 | 2 | 3
4| 5| 6

File 2
EPSILON|GREEK|OMEGA|BETA
7| 8| 9| 0
12| | 13|
10| 11| 5| 15

End result should be:

ALPHA|OMEGA|GAMMA|EPSILON|GREEK|BETA
1 | 2 | 3 |
| |
4 | 5 | 6 | 10|
11| 15
| 9| | 7|
8| 0
| 13| | 12|
|



Currently I have tried this:

array_file1 = []
array_file2 = []

row = 0
IO.foreach("file1.txt" ) {
|line|
array_file1[row] = line.split("|")
row += 1
}

row = 0
IO.foreach("file2" ) {
|line|
array_file2[row] = line.split("|")
row += 1
}
N = array_file1.length
array_file1.times(N) { |row|
if array_file1[row][1] == array_file2[row][2]
array_file2[row].each{
|col|
array_file1[row][array_file1i[row].length] = col
}
end
}

But I get Undefined Method

Logically, I want to
loop through row of array_file 1{
check to see if array_file1.OMEGA is equal to array_file2.OMEGA
loop through column
insert contents of array_file2 to end of array_file1
end loop
end loop


Any help would be greatly appreciated!
 
Reply With Quote
 
 
 
 
7stud --
Guest
Posts: n/a
 
      02-25-2009
lionbarrage wrote:
>
> File 1
> ALPHA|OMEGA|GAMMA
> 1 | 2 | 3
> 4| 5| 6
>
> File 2
> EPSILON|GREEK|OMEGA|BETA
> 7| 8| 9| 0
> 12| | 13|
> 10| 11| 5| 15
>
> End result should be:
>
> ALPHA|OMEGA|GAMMA|EPSILON|GREEK|BETA
> 1 | 2 | 3 |
> | |
> 4 | 5 | 6 | 10|
> 11| 15
> | 9| | 7|
> 8| 0
> | 13| | 12|
> |
>



Wow. What made you think you could tackle ascii art? And were you
actually satisfied with the result?
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Simon Krahnke
Guest
Posts: n/a
 
      02-25-2009
* lionbarrage <> (02:17) schrieb:

> File 1
> ALPHA|OMEGA|GAMMA
> 1 | 2 | 3
> 4 | 5 | 6
>
> File 2
> EPSILON|GREEK|OMEGA|BETA
> 7 | 8 | 9 | 0
> 12 | | 13 |
> 10 | 11 | 5 | 15
>
> End result should be:
>
> ALPHA|OMEGA|GAMMA|EPSILON|GREEK|BETA
> 1 | 2 | 3 | | |
> 4 | 5 | 6 | 10 | 11 | 15
> | 9 | | 7 | 8 | 0
> | 13 | | 12 | |


I hoped I fixed your ASCII art the right way.

In understand that this represents named sets of integers that are to be
merged. Right?

The natural representation of that would be a hash containing sets.
There is a set class, but I use arrays here:

require 'pp'

sets = Hash.new { | h, k | h[k] = [] } # hash that contains a new array
# for every new key
%w(file1.txt file2).each do | filename |
File.open(filename) do | f |
names = f.gets.chop.split('|')
f.each do | line |
names.zip(line.chop.split('|')).each do | name, value |
sets[name] << value
end
end
end
end

pp sets

This code does no tabular printing, treats the "integers" as strings,
without excluding empty strings and doubles. But that could easily be
fixed.

Probably I got it all wrong.

mfg, simon .... l
 
Reply With Quote
 
lionbarrage
Guest
Posts: n/a
 
      02-26-2009
On Feb 24, 8:58*pm, Simon Krahnke <overl...@gmx.li> wrote:
> * lionbarrage <cmakali...@gmail.com> (02:17) schrieb:
>
>
>
> > File 1
> > ALPHA|OMEGA|GAMMA
> > * * * * * 1 | * * * * 2 | * * * * * 3
> > * * * * * 4 | * * * * 5 | * * * * * 6

>
> > File 2
> > EPSILON|GREEK|OMEGA|BETA
> > * * * * * 7 | * * * * 8 | * * * * * 9 | ** * *0
> > * * * * *12 | * * * * * | * * * * *13 |
> > * * * * *10 | * * * *11 | * * * * * 5 | ** * 15

>
> > End result should be:

>
> > ALPHA|OMEGA|GAMMA|EPSILON|GREEK|BETA
> > * * * * * 1 | * * * * 2 | * * * * * 3 | ** * * *| * * * * *|
> > * * * * * 4 | * * * * 5 | * * * * * 6 | ** * 10 | * * * 11 | * * 15
> > * * * * * * | * * * * 9 | * * * * * * |* * * *7 | * * * *8 | * * *0
> > * * * * * * | * * * *13 | * * * * * * |* * * 12 | * * * * *|

>
> I hoped I fixed your ASCII art the right way.
>
> In understand that this represents named sets of integers that are to be
> merged. Right?
>
> The natural representation of that would be a hash containing sets.
> There is a set class, but I use arrays here:
>
> require 'pp'
>
> sets = Hash.new { | h, k | h[k] = [] } # hash that contains a newarray
> * * * * * * * * * * * * * * * * * * * *# for every new key
> %w(file1.txt file2).each do | filename |
> * File.open(filename) do | f |
> * * names = f.gets.chop.split('|')
> * * f.each do | line |
> * * * *names.zip(line.chop.split('|')).each do | name, value |
> * * * * *sets[name] << value
> * * * *end
> * * end
> * end
> end
>
> pp sets
>
> This code does no tabular printing, treats the "integers" as strings,
> without excluding empty strings and doubles. But that could easily be
> fixed.
>
> Probably I got it all wrong.
>
> mfg, * * * * * * * * * * * *simon .... l


Thanks for fixing my art, looked fine in my screen but I guess the
translation was off.

I'm not too familiar with hashes but the code you wrote seems to be
doing it. Thank you so much!!

How do i refer to a single element within a hash? Let's say I want
11 for example. Would I do sets["GREEK"][3]?

THANK YOU!



 
Reply With Quote
 
Simon Krahnke
Guest
Posts: n/a
 
      02-26-2009
* lionbarrage <> (08:11) schrieb:

> I'm not too familiar with hashes but the code you wrote seems to be
> doing it. Thank you so much!!


Hashes are just like arrays, only the keys can be anything and not just
integers.

> How do i refer to a single element within a hash?


Simply by sets['GREEK'], but that single element is an array.

> Let's say I want 11 for example. Would I do sets["GREEK"][3]?


Yes, sets['GREEK'][1] should do.

mfg, simon .... l
 
Reply With Quote
 
lionbarrage
Guest
Posts: n/a
 
      02-27-2009
On Feb 26, 4:51*am, Simon Krahnke <overl...@gmx.li> wrote:
> * lionbarrage <cmakali...@gmail.com> (08:11) schrieb:
>
> > I'm not too familiar with hashes but the code you wrote seems to be
> > doing it. Thank you so much!!

>
> Hashes are just like arrays, only the keys can be anything and not just
> integers.
>
> > How do i refer to a single element within a hash?

>
> Simply by sets['GREEK'], but that single element is anarray.
>
> > Let's say I want 11 for example. *Would I do sets["GREEK"][3]?

>
> Yes, sets['GREEK'][1] should do.
>
> mfg, * * * * * * * * * * * simon .... l



Thanks! I did:
sets.keys.each{|k|
print k, "|"
}
print "\n"
sets.values.each { |v|
pp v
}
which got me:

ALPHA|OMEGA|GAMMA|EPSILON|GREEK|BETA|
["1", "4"]
["2", "5", "9", "13", "5"]
["3", nil]
["7", "12", "10"]
["8", "", "11"]
["0", nil, "1"]

Is there a format function which will remove "" and change , to | ?

Thanks tons!


 
Reply With Quote
 
Simon Krahnke
Guest
Posts: n/a
 
      02-28-2009
* lionbarrage <> (2009-02-27) schrieb:

> Thanks! I did:
> sets.keys.each{|k|
> print k, "|"
> }
> print "\n"


You could just do

puts set.keys.join('|')

To have the value output you specified in you original post, is a little
more complicated.

> Is there a format function which will remove "" and change , to | ?


Don't use pp for production use. Do your own formatting. Here's my
updated script:

,----[ sets.rb ]
| #!/usr/bin/env ruby
|
| sets = Hash.new { | h, k | h[k] = [] } # hash that contains a new array
| # for every new key
| %w(file1.txt file2).each do | filename |
| File.open(filename) do | f |
| names = f.gets.chop.split('|')
| f.each do | line |
| names.zip(line.chop.split('|')).each do | name, value |
| sets[name] << value.to_i if value and value !~ /^\s*$/
| end
| end
| end
| end
|
| sets.values.each { | a | a.uniq! }
|
| puts sets.keys.map { | k | '%8s ' % k }.join('|')
|
| rows = sets.values.map { | a | a.size }.max
|
| (1..rows).zip(*sets.values) do | row |
| row.shift
| puts row.map { | v | if v then '%8s ' % v else ' '*9 end }.join('|')
| end
`----

,----[ output ]
| GAMMA | OMEGA | GREEK | BETA | ALPHA | EPSILON
| 3 | 2 | 8 | 0 | 1 | 7
| 6 | 5 | 11 | 15 | 4 | 12
| | 9 | | | | 10
| | 13 | | | |
`----

If you don't understand the code, please ask.

mfg, simon .... l
 
Reply With Quote
 
Simon Krahnke
Guest
Posts: n/a
 
      03-02-2009
* Simon Krahnke <> (2009-02-2 schrieb:

>| puts row.map { | v | if v then '%8s ' % v else ' '*9 end }.join('|')


Actually, since nil.to_s == "" you can do this simpler:

| puts row.map { | v | '%8s ' % v }.join('|')

mfg, simon .... l
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
To convert a one dimensional array into a two dimensional array using C amrutha0303 Software 0 08-03-2010 10:02 PM
multi-dimensional arrays to 2-dimensional arrays Wirianto Djunaidi Ruby 2 04-29-2008 07:31 AM
Help defining multi-dimensional array Victor Reyes Ruby 5 12-11-2005 04:51 AM
need help with list of lists ( multi dimensional array) news-acct Perl Misc 6 08-28-2005 02:01 PM
How do copy Strings from a single dimensional array to double dimensional array Venkat C++ 4 12-05-2003 09:23 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57