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

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Gilbert L. (Guest)
on 2007-06-16 16:33
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.
Harry K. (Guest)
on 2007-06-16 17:09
(Received via mailing list)
On 6/16/07, Gilbert L. <removed_email_address@domain.invalid> wrote:
> Starbuck => [1,2]
>
> --
> Posted via http://www.ruby-forum.com/.
>
>

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

--

A Look into Japanese Ruby List in English
http://www.kakueki.com/
Gilbert L. (Guest)
on 2007-06-16 18:52
Harry K. wrote:
> myhash = {}
> myhash["Starbuck"] = []
> myhash["Starbuck"] << [1,2]
> myhash["Starbuck"] << [1,7]
>
> p myhash
> p myhash["Starbuck"][1]
> p myhash["Starbuck"][1][1]
>
>
> Harry
>
> --
>
> A Look into Japanese Ruby List in English
> http://www.kakueki.com/

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?
Harry K. (Guest)
on 2007-06-17 03:16
(Received via mailing list)
On 6/16/07, Gilbert L. <removed_email_address@domain.invalid> wrote:
>
> 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

--

A Look into Japanese Ruby List in English
http://www.kakueki.com/
Gilbert L. (Guest)
on 2007-06-18 06:08
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"
Harry K. (Guest)
on 2007-06-18 07:08
(Received via mailing list)
On 6/18/07, Gilbert L. <removed_email_address@domain.invalid> wrote:
> 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

--

A Look into Japanese Ruby List in English
http://www.kakueki.com/
Peña, Botp (Guest)
on 2007-06-18 07:08
(Received via mailing list)
On Behalf Of Gilbert L.:
# 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"

just be careful w some value clashes

irb(main):112:0> newhash={}
=> {}
irb(main):113:0> myhash.each{|k,v| v.each{|e| newhash[e]=k}}
=> {"a"=>[[0, 0], [3, 4]], "b"=>[[1, 1], [9, 8]], "c"=>[[7, 6]]}

# we create a new hash whose values are now keys
# (like invert but your case is special)
# so now values still point to their original keys

irb(main):114:0> newhash
=> {[0, 0]=>"a", [1, 1]=>"b", [3, 4]=>"a", [7, 6]=>"c", [9, 8]=>"b"}
irb(main):118:0> newhash.keys
=> [[0, 0], [1, 1], [3, 4], [7, 6], [9, 8]]
irb(main):119:0> newhash.values
=> ["a", "b", "a", "c", "b"]
irb(main):120:0>

there is too much magic in there, i'm not sure how/why ruby sorted it
(but i love it :)

anyway, just to be sure

irb(main):145:0> newhash.sort_by{|k,v| k}
=> [[[0, 0], "a"], [[1, 1], "b"], [[3, 4], "a"], [[7, 6], "c"], [[9, 8],
"b"]]
irb(main):146:0> newhash.sort_by{|k,v| k}.map{|e| e[0]}
=> [[0, 0], [1, 1], [3, 4], [7, 6], [9, 8]]
irb(main):147:0> newhash.sort_by{|k,v| k}.map{|e| e[1]}
=> ["a", "b", "a", "c", "b"]

kind regards -botp
unknown (Guest)
on 2007-06-18 14:31
(Received via mailing list)
Hi --

On Mon, 18 Jun 2007, Harry K. wrote:

>>
>
>
>
> # 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
Gilbert L. (Guest)
on 2007-06-18 15:33
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
Todd B. (Guest)
on 2007-06-18 22:43
(Received via mailing list)
On 6/18/07, Gilbert L. <removed_email_address@domain.invalid> wrote:
>
> 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
Todd B. (Guest)
on 2007-06-18 23:09
(Received via mailing list)
On 6/18/07, Todd B. <removed_email_address@domain.invalid> wrote:
> 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
   ^^^ delete the accidental "end" here

> sorted = a.select {|coord| a.include?(coord.up) ||
> a.include?(coord.down) )}.sort
>
> p sorted

sorry 'bout that
Gilbert L. (Guest)
on 2007-06-19 00:39
Todd B. wrote:
> 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.
This topic is locked and can not be replied to.