# Simple match of items in 2 arrays

**URL:** <https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929>\
**Category:** Ruby\
**Created:** [January 9, 2006, 10:19am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929 "2006-01-09T10:19:40Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 9, 2006, 10:19am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/1 "2006-01-09T10:19:40Z")

</div>

Hi

Inexperienced ruby user question:

I have 2 large csv files:

1. Zipdata = basically a frequency table of zipcodes:  
02115, 10  
64108, 9  
99234, 8 etc

2. Ziplookup (ziplu) = several column table of data assoc with  
zipcodes:  
02115, +43.59906, -75,99343, Hoboken, NJ, Johnson Cty  
55021, +55.5454, - 64,8585, Kansas City, MO, Jackson Cty

I am trying to take each entry in the zipdata and compare the zipcode  
to the lookup table  
When a match is found, combine the data into a new line /  
multidimensional hash table eg -  
02115, 10, +43.59906, -75,99343, Hoboken, NJ, Johnson Cty

Here is what I have:  
outf = File.read “ZIP\_CODES.txt”  
ziplu=[]  
zipdata = []  
result = []

outf.each {|e| ziplu.push e.chomp}

# open the csv file of zip code occurences and their frequency (zips),

and add each zipcode to an array (zipdata)  
doc = File.read “zips.txt”  
doc.each {|f| zipdata.push f}

#compare each line from zipsdata to the lookup file and put into new  
array  
result.push(zipdata.each {|a| ziplu.find\_all{|x| /a/ =~ x})

I can’t get the comparison to work, and don’t know what format to put  
the result into (hash, array of arrays, file) - from which I can  
easily output the results (ie., lat long, city, state) by zipcode…

Any guidance appreciated…

CLS

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 9, 2006, 11:15am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/2 "2006-01-09T11:15:53Z")

</div>

Charles L. Snyder wrote:

> I can’t get the comparison to work, and don’t know what format to put  
> the result into (hash, array of arrays, file) - from which I can  
> easily output the results (ie., lat long, city, state) by zipcode…
> 
> Any guidance appreciated…

Charles,

I don’t konw if this is the best way of doing it, but it works at least.  
btw, your file has errors. It the code supposed to deal with them?  
e.g. commas in the latitude, spaces after minus.  
Have you considered using a database table?

Christer

class ZipCodeReader  
ZipCode = Struct.new(:zipcode, :lat, :lng, :address, :state, :city,  
:freq)  
def read(filename)  
@zipcode = {}  
IO.foreach(filename) do |line|  
arr = line.chomp.split(",")  
zipcode = ZipCode.new(arr[0], arr[1].to\_f, arr[2].to\_f,  
arr[3].lstrip, arr[4].lstrip, arr[5].lstrip, 0)  
@zipcode[arr[0]] = zipcode  
end  
end

def readfreq(filename)  
IO.foreach(filename) do |line|  
arr = line.chomp.split(",")  
@zipcode[arr[0]].freq = arr[1].lstrip.to\_i unless  
@zipcode[arr[0]].nil?  
end  
end

def dump  
arr=@zipcode.sort  
arr.each {|x| print x.to\_s + “\n”}  
end  
end

zipcode=ZipCodeReader.new  
zipcode.read(“zipcode.txt”)  
zipcode.readfreq(“zipdata.txt”)  
zipcode.dump

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 9, 2006, 11:28am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/3 "2006-01-09T11:28:57Z")

</div>

Hi,

You can use the CSV module. As Christer already pointed out, you have  
errors in your CSV file.

Robin

require ‘csv’  
require ‘yaml’

zips = {}

ziplookup = CSV.parse(File.read(‘ziplu’), ', ')  
zipdata = CSV.parse(File.read(‘zipdata’), ', ')

zipdata.each do |data|  
zip\_code = data.first  
h = {}  
zips[zip\_code] = h  
h[:frequency] = data[1].to\_i  
lookup = ziplookup.find{ |lookup| lookup.first == zip\_code }  
next unless lookup

# something like this:

h[:lat] = lookup[1].gsub(’,’, ‘.’).to\_f  
h[:long] = lookup[2].gsub(’,’, ‘.’).to\_f  
h[:city] = lookup[3]  
end

y zips

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 9, 2006, 1:35pm UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/4 "2006-01-09T13:35:35Z")

</div>

Robin S. wrote:

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 9, 2006, 1:50pm UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/5 "2006-01-09T13:50:44Z")

</div>

Robin S. wrote:

> h[:frequency] = data[1].to\_i  
> lookup = ziplookup.find{ |lookup| lookup.first == zip\_code }  
> next unless lookup
> 
> # something like this:
> 
> h[:lat] = lookup[1].gsub(’,’, ‘.’).to\_f  
> h[:long] = lookup[2].gsub(’,’, ‘.’).to\_f  
> h[:city] = lookup[3]  
> end
> 
> y zips

I’d change this a bit:

- read only lookup zips into mem and process the other line by line  
(saves mem)
- use a hash for lookup

# untested

require ‘csv’

zips = File.open(‘ziplu’) do |io|  
h = {}  
io.each\_line do |line|  
zip, freq = CSV.parse\_line  
h[zip]=freq  
end  
h  
end

File.open(‘zipdata’) do |io|  
io.each\_line do |line|  
rec = CSV.parse\_line line  
freq = zips[rec[0]] or next  
rec[1,0]=freq  
puts rec.join ‘,’  
end  
end

HTH

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 10, 2006, 2:42am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/6 "2006-01-10T02:42:08Z")

</div>

Charles L. Snyder wrote:

> Thanks everyone - Robert’s method works for me with minor alteration.  
> The errors in the example were not in the actual file.
> 
> BTW:  
> Christer’s answer gives me:  
> “undefined method `lstrip’ for nil:NilClass (NoMethodError)”
> 
> Robin’s method gives me:  
> private method `gsub’ called for nil:NilClass (NoMethodError)
> 
> Thanks to all !

CLS,

can you give me some problem input?

Christer

---

<div class="post-metadata">

**Author:** ![Charles\_LSSnyder](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/c2a13f/32.png) [@Charles\_LSSnyder](https://www.ruby-forum.com/u/Charles_LSSnyder)\
**Post date:** [January 10, 2006, 2:38am UTC](https://www.ruby-forum.com/t/simple-match-of-items-in-2-arrays/51929/7 "2006-01-10T02:38:51Z")

</div>

Thanks everyone - Robert’s method works for me with minor alteration.  
The errors in the example were not in the actual file.

BTW:  
Christer’s answer gives me:  
“undefined method `lstrip’ for nil:NilClass (NoMethodError)”

Robin’s method gives me:  
private method `gsub’ called for nil:NilClass (NoMethodError)

Thanks to all !
