Adding new value (in array) to existing key in a hash

G

Gilbert Lau

Hi all,

Am new to programming am learning to use ruby to code a program. How do
I add a new value to existing key without overwriting the old value?
Went to documentation, but didn't find anything that can help me.
Searched on google as well and in vain.

Say I have a value of coordinate [i,j] and am using a hash table to
store these coordinates for a specific location. Let's say,

Starbuck => [1,2]

How to I append or add a new coordinate of [1,7] to Starbuck? to become,

Starbuck => [1,2], [1,7]

And able to retrieve each individual coordinates later in array as well.
The idea behind the code is iterate, if new location for Starbuck is
found, add the location in i,j format to key "starbuck".

Thanks a lot for your help.
 
H

Harry Kakueki

Hi all,

Am new to programming am learning to use ruby to code a program. How do
I add a new value to existing key without overwriting the old value?
Went to documentation, but didn't find anything that can help me.
Searched on google as well and in vain.

Say I have a value of coordinate [i,j] and am using a hash table to
store these coordinates for a specific location. Let's say,

Starbuck => [1,2]

How to I append or add a new coordinate of [1,7] to Starbuck? to become,

Starbuck => [1,2], [1,7]

And able to retrieve each individual coordinates later in array as well.
The idea behind the code is iterate, if new location for Starbuck is
found, add the location in i,j format to key "starbuck".

Thanks a lot for your help.

If I understood you correctly,
try something like this.

myhash = {}
myhash["Starbuck"] = []
myhash["Starbuck"] << [1,2]
myhash["Starbuck"] << [1,7]

p myhash
p myhash["Starbuck"][1]
p myhash["Starbuck"][1][1]


Harry
 
G

Gilbert Lau

Harry said:
myhash = {}
myhash["Starbuck"] = []
myhash["Starbuck"] << [1,2]
myhash["Starbuck"] << [1,7]

p myhash
p myhash["Starbuck"][1]
p myhash["Starbuck"][1][1]


Harry

Thanks a lot. Didn't know it can be so easy.

Correct me if I am wrong... the = [] means that i initiate the value for
the hash as array first before I input the values as array [i,j] into
the hash. Is that the explanation for the code above?
 
H

Harry Kakueki

Correct me if I am wrong... the = [] means that i initiate the value for
the hash as array first before I input the values as array [i,j] into
the hash. Is that the explanation for the code above?

Yes, it sets up the value as an array and pushes arrays into that array.
This does the same.

myhash = Hash.new
myhash["Starbuck"] = Array.new
myhash["Starbuck"].push([1,2])
myhash["Starbuck"].push([1,7])

p myhash
p myhash["Starbuck"][1]
p myhash["Starbuck"][1][1]

Harry
 
G

Gilbert Lau

Thanks a lot. Sorry, got another question

let's say that the hash is

myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6]]}

how do I sort the values to become

[0,0],[1,1],[3,4],[7,6],[9,8]

and be able to recall the keys to arrange according to the sorted
values, like

"a", "b", "a", "c", "b"
 
H

Harry Kakueki

Thanks a lot. Sorry, got another question

let's say that the hash is

myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6]]}

how do I sort the values to become

[0,0],[1,1],[3,4],[7,6],[9,8]

and be able to recall the keys to arrange according to the sorted
values, like

"a", "b", "a", "c", "b"

Well, I think this will work.
Extract the arrays from the values and then sort.

myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6]]}

arr = []
myhash.each_value do |x|
x.each {|y| arr << y}
end

p arr.sort!

# This will find whether it is included in "a" for example
# but you need to think about what to do if you have duplicates.
# myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[0,0],[9,8]], "c" => [[7,6]]}


# This is ugly but maybe you can get some ideas
arr.each do |c|
p "FROM a" if myhash["a"].include?(c)
p "NOT FROM a" unless myhash["a"].include?(c)
end

Harry
 
D

dblack

Hi --

Thanks a lot. Sorry, got another question

let's say that the hash is

myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6]]}

how do I sort the values to become

[0,0],[1,1],[3,4],[7,6],[9,8]

and be able to recall the keys to arrange according to the sorted
values, like

"a", "b", "a", "c", "b"

Well, I think this will work.
Extract the arrays from the values and then sort.

myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6]]}

arr = []
myhash.each_value do |x|
x.each {|y| arr << y}
end

p arr.sort!

# This will find whether it is included in "a" for example
# but you need to think about what to do if you have duplicates.
# myhash = {"a" => [[0,0],[3,4]], "b" => [[1,1],[0,0],[9,8]], "c" => [[7,6]]}


# This is ugly but maybe you can get some ideas
arr.each do |c|
p "FROM a" if myhash["a"].include?(c)
p "NOT FROM a" unless myhash["a"].include?(c)
end

One way to generalize it:

arr.sort.map {|c| myhash.keys.find {|k| myhash[k].include?(c) } }

There's probably a more efficient way (there usually is when I'm the
first to suggest these things :) but that will get you the whole
array.


David

--
* Books:
RAILS ROUTING (new! http://safari.awprofessional.com/9780321509246)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
G

Gilbert Lau

Thanks a million. But still I have another problem. Figure that I can
take it on from all your guys' help, but I can't.

A more controlled sort. I only want to sort the keys where the values
from myhash follows this pattern of [i,j], [i+1,j+1]... think of it as
a 2-D matrix and I am only interested in the diagonal line. I am not
worried about the duplicates of coordinates, as one coordinates can only
have one occurrence(or building).

For example, the sorted result for the following hash will be:

myhash = {"a"=>[[0, 0], [3, 4]], "b"=>[[1, 1], [9, 8]], "c"=>[[7, 6],[4,
5]}

[[0, 0], [1, 1], [3, 4], [4, 5]]
"a", "b", "a", "c"

Cheers
 
T

Todd Benson

Thanks a million. But still I have another problem. Figure that I can
take it on from all your guys' help, but I can't.

A more controlled sort. I only want to sort the keys where the values
from myhash follows this pattern of [i,j], [i+1,j+1]... think of it as
a 2-D matrix and I am only interested in the diagonal line. I am not
worried about the duplicates of coordinates, as one coordinates can only
have one occurrence(or building).

For example, the sorted result for the following hash will be:

myhash = {"a"=>[[0, 0], [3, 4]], "b"=>[[1, 1], [9, 8]], "c"=>[[7, 6],[4,
5]}

[[0, 0], [1, 1], [3, 4], [4, 5]]
"a", "b", "a", "c"

Do you mean that [7,6] is not included becuase there is no [6,5] or
[8,7]? You shouldn't open up core classes and you don't have to for
this, but it makes it more readable:

class Array
def up; map {|i| i+1}; end
def down; map {|i| i-1}; end
end
h = { "a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6],[4,5]] }
a = []
h.each_value {|v| v.each {|coord| a << coord}}
end
sorted = a.select {|coord| a.include?(coord.up) ||
a.include?(coord.down) )}.sort

p sorted
 
T

Todd Benson

class Array
def up; map {|i| i+1}; end
def down; map {|i| i-1}; end
end
h = { "a" => [[0,0],[3,4]], "b" => [[1,1],[9,8]], "c" => [[7,6],[4,5]] }
a = []
h.each_value {|v| v.each {|coord| a << coord}}
^^^ delete the accidental "end" here
sorted = a.select {|coord| a.include?(coord.up) ||
a.include?(coord.down) )}.sort

p sorted

sorry 'bout that
 
G

Gilbert Lau

Todd said:
Do you mean that [7,6] is not included becuase there is no [6,5] or
[8,7]?

Yes. I am only interested in coordinates that fit the pattern of [i, j],
[i+1, j+1].. This is way too advance for me. But thank you guys for all
your help. I learned a lot.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,262
Messages
2,571,310
Members
47,978
Latest member
SheriBolli

Latest Threads

Top