Hash table

16 views
Skip to first unread message

Suo Huang

unread,
Dec 16, 2015, 4:43:47 PM12/16/15
to Ruby on Rails: Talk
Hi all,

I am a newbie in Ruby, and I am having a small question with the hash table. If anyone could give me some suggestions that would be great!

Considering creating a hash table like this:

 a_Min a_Max     b_Min          b_Max p1      p2          p3            p4             p5          p6
40.000 47.95 -95.0         -74.01 12.8  6.5  177.82    0.9150     68.62    0.9020
42.000 47.95 -68.0  -59.50 11.0  5.8  185.20    0.9377     -11.80    0.9538
44.000 47.95 -74.2  -68.05 12.8  6.5  157.45    0.9194     37.55    0.9297
46.000 66.00 -59.5  -51.00 8.8 3.7  164.96    0.9465     -207.54     1.0342
47.951 66.00 -79.0  -59.55 12.8 6.5  157.45    0.9194     37.55    0.9297
47.951 66.00 -95.0  -79.01 12.8 6.5  177.82    0.9150     68.62    0.9020
...

If giving any (a,b), it will fall within the four boundary control values in the hash table (a_Min, a_Max, b_min, b_Max) and returns its relative parameters (p1, p2, p3....)

I am trying something like this:

def functionXXX(a, b)
    threshold = XXX                                      # how to create a hash table with the above data?
    for t in threshold do
   if (t[:a_Min]<=a && a<t[:a_Max] && t[:b_Min]<=b && b<t[:b_Max]) then    #if there is a smarter way in Ruby for this?
      return t
      break
    end
    end
end

Would this be the correct way of doing this task in Ruby?

Thanks!

Suo

Scott Eisenberg

unread,
Dec 16, 2015, 5:25:21 PM12/16/15
to rubyonra...@googlegroups.com
Looks to me like you will have an Array of hashes.

The ruby way something like a single line array select

 t.select{|tt| a.between?(tt[:min], tt[:max]) && b.between?(tt[:b_min], tt[:b_max])}

create the array initially with something like

t = Array.new
t << {a_min: 1, a_max:10, b_min: 100, b_max: 1000, p1: 1, p2: 2, p3: 3} 
t << {a_min: 1, a_max:10, b_min: 100, b_max: 1000, p1: 1, p2: 2, p3: 3}  

(fill in your data)

you could do t = [{your data}, {your hash data}….]

If you only want the first value in the array that matches, use t.detect rather than t.select

It will return either any array of matching hashes or with detect the first one…


Use the rails console to test all this stuff.  rails c




--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
To post to this group, send email to rubyonra...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/97f8d9fe-4632-49cd-a5d7-aeb80da4472b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rob Biedenharn

unread,
Dec 16, 2015, 9:19:57 PM12/16/15
to rubyonra...@googlegroups.com
On 2015-Dec-16, at 17:24 , Scott Eisenberg <sco...@btrtrucks.com> wrote:

Looks to me like you will have an Array of hashes.

The ruby way something like a single line array select

 t.select{|tt| a.between?(tt[:min], tt[:max]) && b.between?(tt[:b_min], tt[:b_max])}

create the array initially with something like

t = Array.new
t << {a_min: 1, a_max:10, b_min: 100, b_max: 1000, p1: 1, p2: 2, p3: 3} 
t << {a_min: 1, a_max:10, b_min: 100, b_max: 1000, p1: 1, p2: 2, p3: 3}  

(fill in your data)

you could do t = [{your data}, {your hash data}….]

If you only want the first value in the array that matches, use t.detect rather than t.select

It will return either any array of matching hashes or with detect the first one…


Use the rails console to test all this stuff.  rails c


Or, use the fact that you have a well-defined range for the 'a' and 'b'

TABLE = [
  {a: 40.000..47.95, b: -95.0..-74.01, p1: 12.8, p2: 6.5, p3: 177.82, p4: 0.9150, p5:   68.62, p6: 0.9020},
  {a: 42.000..47.95, b: -68.0..-59.50, p1: 11.0, p2: 5.8, p3: 185.20, p4: 0.9377, p5:  -11.80, p6: 0.9538},
  {a: 44.000..47.95, b: -74.2..-68.05, p1: 12.8, p2: 6.5, p3: 157.45, p4: 0.9194, p5:   37.55, p6: 0.9297},
  {a: 46.000..66.00, b: -59.5..-51.00, p1:  8.8, p2: 3.7, p3: 164.96, p4: 0.9465, p5: -207.54, p6: 1.0342},
  {a: 47.951..66.00, b: -79.0..-59.55, p1: 12.8, p2: 6.5, p3: 157.45, p4: 0.9194, p5:   37.55, p6: 0.9297},
  {a: 47.951..66.00, b: -95.0..-79.01, p1: 12.8, p2: 6.5, p3: 177.82, p4: 0.9150, p5:   68.62, p6: 0.9020},
];
def params(a:, b:)
  TABLE.detect {|h| h[:a].cover?(a) && h[:b].cover?(b) }
end

irb2.2.3> params(a: 45.2, b: -70)
#2.2.3 => {:a=>44.0..47.95, :b=>-74.2..-68.05, :p1=>12.8, :p2=>6.5, :p3=>157.45, :p4=>0.9194, :p5=>37.55, :p6=>0.9297}

Obviously build your table as big as you need, but you might have to think about a more suitable data structure if this crude linear search through an array isn't fast enough.

-Rob

Reply all
Reply to author
Forward
0 new messages