Order of fields and values in a hash

Not sure if I'm being paranoid or not. But my code has to work in multiple flavours of Ruby, so.

Let's say we have a hash h, and

      x = h.keys.zip(h.values).to_h

How confident can I be that x == h? In other words, how confident can I be that h.keys will give the same ordering of hash elements as h.values?

I see that the doc for Hash in MRI says "Hashes enumerate their values in the order that the corresponding keys were inserted". Can I really rely on that? In jRuby to?

I suppose I am used to the idea that you can't rely on the ordering of elements in a Hash. It would simplify things if I could, though.

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>

Not sure if I’m being paranoid or not. But my code has to work in multiple
flavours of Ruby, so.

Let’s say we have a hash h, and

      x = h.keys.zip(h.values).to_h

What is it that you _really_ want to achieve?

How confident can I be that x == h? In other words, how confident can I be
that h.keys will give the same ordering of hash elements as h.values?

I would not rely on order between calls. Either access pairs directly
or map keys via the Hash to their values:

irb(main):001:0> h={1=>2,3=>4}
=> {1=>2, 3=>4}
irb(main):002:0> h.to_a
=> [[1, 2], [3, 4]]
irb(main):003:0> h.to_a.to_h
=> {1=>2, 3=>4}

irb(main):004:0> k = h.keys
=> [1, 3]
irb(main):005:0> k.zip(k.map{|x|h})
=> [[1, 2], [3, 4]]
irb(main):006:0> k.zip(k.map{|x|h}).to_h
=> {1=>2, 3=>4}

I see that the doc for Hash in MRI says “Hashes enumerate their values in
the order that the corresponding keys were inserted”. Can I really rely on
that? In jRuby to?

I suppose I am used to the idea that you can’t rely on the ordering of
elements in a Hash.

Same here.

It would simplify things if I could, though.

Simplify things today - and get burned tomorrow. :slight_smile:

Cheers

robert

···

On Thu, Nov 3, 2016 at 4:04 PM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

--
[guy, jim, charlie].each {|him| remember.him do |as, often| as.you_can
- without end}
http://blog.rubybestpractices.com/

      x = h.keys.zip(h.values).to_h

How confident can I be that x == h? In other words, how confident can I be
that h.keys will give the same ordering of hash elements as h.values?

i am 100% confident. because i always do this, and i dont remember how long : )

I suppose I am used to the idea that you can’t rely on the ordering of
elements in a Hash.

as long as i dont touch h while generating its keys and values, i
should be fine

best regards
--botp

···

On Thu, Nov 3, 2016 at 11:04 PM, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

Yep, it became part of the Ruby specification in 1.9.

If you want to be paranoid, though, you can always keep a copy of
h.to_a around, as h.keys==h.to_a.map(&:first) and
h.values==h.to_a.map(&:last)

But as I said, hash ordering has been spec for 9 years so far.

Cheers

···

On 04/11/2016, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:

How confident can I be that x == h? In other words, how confident can I be
that h.keys will give the same ordering of hash elements as h.values?

I see that the doc for Hash in MRI says "Hashes enumerate their values in
the order that the corresponding keys were inserted". Can I really rely on
that? In jRuby to?

--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Just to draw parallels, it's called a "guarantee", at least in Perl, that the keys are same for subsequent read operators, until they are reset.

···

On Nov 3, 2016, at 14:01, Matthew Kerwin <matthew@kerwin.net.au> wrote:

On 04/11/2016, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:
How confident can I be that x == h? In other words, how confident can I be
that h.keys will give the same ordering of hash elements as h.values?

I see that the doc for Hash in MRI says "Hashes enumerate their values in
the order that the corresponding keys were inserted". Can I really rely on
that? In jRuby to?

Yep, it became part of the Ruby specification in 1.9.

If you want to be paranoid, though, you can always keep a copy of
h.to_a around, as h.keys==h.to_a.map(&:first) and
h.values==h.to_a.map(&:last)

But as I said, hash ordering has been spec for 9 years so far.

Cheers
--
Matthew Kerwin
http://matthew.kerwin.net.au/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

>
> Let’s say we have a hash h, and
>
> x = h.keys.zip(h.values).to_h

What is it that you _really_ want to achieve?

Really? I have a hash of fieldnames and values and I want to turn them into SQL.

This is for a mixin to provide basic SQL for another class. So there is a method that turns the keys into SQL with placeholders, and then at some later point I want to get the corresponding values out of the hash and use them in something DB-interface-specific so that the DB interface will insert the values in the SQL. Because, of course, I shouldn't be the one to do that, unless I want to be vulnerable to SQL insertion...

Now you know why I gave a simple example!

Feel free to laugh at my mad science yourself if you desire: https://bitbucket.org/andy-twosticks/pod4

Right now it works, but without protection from SQL injection it is, pardon my French, a bit shit. So that's the next step.

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer&gt;

I think that even longer it has been the case that the permutation
enumerated by Hash#keys and Hash#values has been aligned if the hash is not
altered in between. The guarantee that was more recently introduced is
about insertion order as it influences the enumeration order.

-Rob

···

On Thu, Nov 3, 2016, 17:01 Matthew Kerwin <matthew@kerwin.net.au> wrote:

On 04/11/2016, Andy Jones <Andy.Jones@jameshall.co.uk> wrote:
> How confident can I be that x == h? In other words, how confident can I
be
> that h.keys will give the same ordering of hash elements as h.values?
>
> I see that the doc for Hash in MRI says "Hashes enumerate their values in
> the order that the corresponding keys were inserted". Can I really rely
on
> that? In jRuby to?
>

Yep, it became part of the Ruby specification in 1.9.

If you want to be paranoid, though, you can always keep a copy of
h.to_a around, as h.keys==h.to_a.map(&:first) and
h.values==h.to_a.map(&:last)

But as I said, hash ordering has been spec for 9 years so far.

Cheers
--
  Matthew Kerwin
  http://matthew.kerwin.net.au/

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;