# Sort hash, hash key and val off by one, see attached

**URL:** <https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432>\
**Category:** Ruby\
**Created:** [January 11, 2009, 8:38am UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432 "2009-01-11T08:38:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 11, 2009, 8:38am UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/1 "2009-01-11T08:38:07Z")

</div>

Please help me with this. I have been trying for days to get this right.  
I don’t see a next method for a hash. Just don’t know what to do. Thanks  
MC

## Temp1.txt

## PersonID,PersonID ID,ID LastName,Social Security \<need to set this val to "no valueâ€ Social Security, Address \<set this key and value to Social Security…and so on Address,Unique ID Unique ID,Potassium

The LastName, Social Security line tells me that there is no value for  
LastName and the next value in the list should be changed to the value  
where Social Security instead of Address.

(my project consist of me comparing 2 files, there is more to it, but i  
just wanted to explain what I am stumped on at this point.)

* * *

File.open(‘Temp.txt’, ‘r+’) do |temp|  
rows = {}  
temp.each\_line do |line|  
key, val = line.chomp.split(",",0)  
rows[key] = val

```
#method to store first value
def storeKey(key,nextval = false)
  storedKey = key
  return storedKey if nextval == true
end

 rows.each do |attrib|
  if rows[key] != key then
   @@newKey = rows[key].to_s
   val1 = storeKey(@@newKey)
   val2 = storeKey(@@newKey,true)
      #if val == nextkey then replace with 'no value'
       if rows[key] == val2 then
          rows[key] = 'no value'
      end
    end
  break
end

```

end

end

---

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 11, 2009, 2:30pm UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/2 "2009-01-11T14:30:27Z")

</div>

Mmcolli00 Mom wrote:

> (my project consist of me comparing 2 files, there is more to it, but i  
> just wanted to explain what I am stumped on at this point.)

I’m afraid your problem makes absolutely no sense at all to me. You  
could try explaining it more clearly, or give an example of the input  
together with the output you expect to get for this entire input.

However I just wanted to point out to you a couple of things:

> temp.each\_line do |line|  
> …  
> #method to store first value  
> def storeKey(key,nextval = false)  
> storedKey = key  
> return storedKey if nextval == true  
> end

Ruby doesn’t support nested methods. What you’re actually doing here is  
defining a new method _every_ time this loop iterates. Better to move  
this outside of the loop (and then it will probably become an instance  
method of a class)

> ```
> @@newKey = rows[key].to_s
> 
> ```

You’re using a class variable here, but it’s not clear why, as you’re  
not inside any class definition; implicitly it ends up as that of the  
‘main’ object. Much better to use a normal local variable. Even a global  
variable ($newKey) would be better.

Also: hashes in ruby 1.8 are unordered. There is no ‘next’ method. If  
there were (or if you iterate through all the elements using ‘each’)  
you’d get them in an arbitrary order.

Regards,

Brian.

---

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 11, 2009, 3:43pm UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/3 "2009-01-11T15:43:48Z")

</div>

I figured it make no sense if I tried to explain it in a nutshell. I  
just need to somehow find the next key in a hash and see if there is a  
match with the current value. If so, then I could insert “no value” then  
make all other lines equal so long as they are a match.

Instead of this…

PersonID,PersonID  
ID,ID  
LastName,Social Security  
Social Security, Address  
Address,Unique ID  
Unique ID,Potassium

It would then look like this…

PersonID,PersonID  
ID,ID  
LastName,“no vale”  
Social Security, Social Security  
Address, Address,  
Unique ID, Unique ID  
Potassium, Potassium

---

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 12, 2009, 1:27pm UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/4 "2009-01-12T13:27:39Z")

</div>

Hi –

On Mon, 12 Jan 2009, Dave B. wrote:

> Mmcolli00 Mom wrote:
> 
> > I just need to somehow find the next key in a hash
> 
> I haven’t read your example, but this statement rings alarm bells. You  
> need to define what you mean by “the next key”. A hash has no natural  
> ordering – it’s just a bunch of key-value pairs – so it’s not obvious  
> what the “next” key means. The order in which you insert pairs is not  
> necessarily the order in which you get them back, and this order may  
> vary from one run to the next. This is basic to hashes.

It’s changing in 1.9, though. 1.9 hashes are ordered by key insertion  
order.

$ ruby -ve ‘p({1=\>“hi”, “a”=\>“bye”, []=\>“whatever”})’  
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-darwin9.5.0]  
{[]=\>“whatever”, “a”=\>“bye”, 1=\>“hi”}

$ ruby19 -ve ‘p({1=\>“hi”, “a”=\>“bye”, []=\>“whatever”})’  
ruby 1.9.1 (2008-12-30 patchlevel-0 revision 21203) [i386-darwin9.5.0]  
{1=\>“hi”, “a”=\>“bye”, []=\>“whatever”}

David

–  
David A. Black / Ruby Power and Light, LLC  
Ruby/Rails consulting & training: [http://www.rubypal.com](http://www.rubypal.com)  
Coming in 2009: The Well-Grounded Rubyist ([The Well-Grounded Rubyist](http://manning.com/black2))

[http://www.wishsight.com](http://www.wishsight.com) =\> Independent, social wishlist management!

---

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 12, 2009, 1:00pm UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/5 "2009-01-12T13:00:48Z")

</div>

Mmcolli00 Mom wrote:

> I just need to somehow find the next key in a hash

I haven’t read your example, but this statement rings alarm bells. You  
need to define what you mean by “the next key”. A hash has no natural  
ordering – it’s just a bunch of key-value pairs – so it’s not obvious  
what the “next” key means. The order in which you insert pairs is not  
necessarily the order in which you get them back, and this order may  
vary from one run to the next. This is basic to hashes.

If you don’t mind the order in which the keys are processed, you can use  
“each” to iterate through the hash.

As a quick fix, you could get all the keys into an array and sort them  
into the order you want (alphabetically, numerically, etc).

Dave

---

<div class="post-metadata">

**Author:** ![mmcolli00](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/85e7bf/32.png) [@mmcolli00](https://www.ruby-forum.com/u/mmcolli00)\
**Post date:** [January 12, 2009, 3:06pm UTC](https://www.ruby-forum.com/t/sort-hash-hash-key-and-val-off-by-one-see-attached/157432/6 "2009-01-12T15:06:42Z")

</div>

Thanks for the advice everyone. I think I might be getting somewhere  
using an array instead since there is no ‘next’ in hashes. - new to  
programming so I was really wasn’t aware of that. Also thanks for the  
tip on the new version and how hashes are ordered by key insertion. Good  
Stuff!  
MC 😉
