# Help with Multi Dimensional Array

**URL:** <https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286>\
**Category:** Ruby\
**Created:** [February 25, 2009, 2:21am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286 "2009-02-25T02:21:51Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 25, 2009, 2:21am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/1 "2009-02-25T02:21:51Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 25, 2009, 2:55am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/2 "2009-02-25T02:55:25Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 25, 2009, 6:05am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/3 "2009-02-25T06:05:35Z")

</div>

- lionbarrage [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (02:17) schrieb:

> 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

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 26, 2009, 8:16am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/4 "2009-02-26T08:16:04Z")

</div>

On Feb 24, 8:58 pm, Simon K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > EPSILON|GREEK|OMEGA|BETA  
> > | 13 | | 12 | |
> 
> end  
> 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!

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 27, 2009, 2:50am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/5 "2009-02-27T02:50:33Z")

</div>

On Feb 26, 4:51 am, Simon K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

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

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 26, 2009, 2:06pm UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/6 "2009-02-26T14:06:17Z")

</div>

- lionbarrage [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (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

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [March 2, 2009, 3:12pm UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/7 "2009-03-02T15:12:04Z")

</div>

- Simon K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (2009-02-28) 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

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [February 28, 2009, 10:06am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/8 "2009-02-28T10:06:25Z")

</div>

- lionbarrage [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (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

---

<div class="post-metadata">

**Author:** ![lionbarrage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/9fc348/32.png) [@lionbarrage](https://www.ruby-forum.com/u/lionbarrage)\
**Post date:** [March 5, 2009, 12:50am UTC](https://www.ruby-forum.com/t/help-with-multi-dimensional-array/161286/9 "2009-03-05T00:50:58Z")

</div>

On Feb 28, 12:33 am, Simon K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> puts set.keys.join(‘|’)  
> | #!/usr/bin/env ruby  
> | end  
> | row.shift  
> `----
> 
> If you don’t understand the code, please ask.
> 
> mfg, simon … l

The output seems a little strange and I’m not sure why that is.

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

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

Please advise on what’s going on.

Thanks
