1

I have a hash here,

    @property_hash = {
    :code => '',
    :fname => '',
    :lname => '',
    :basic_sal => '',
    :emp_type => '',
}

and an array

line = [02,'Firstname', 'LastName', 5800, 'PL']

I want to map the array into the hash like

@property_hash = {
        :code => 02,
        :fname => 'Firstname',
        :lname => 'LastName',
        :basic_sal => 5800,
        :emp_type => 'PL',
    }

what is the best way to do this ?? Thank you

2
  • Can we assume line's order is the same as @property_hash? Commented Apr 19, 2016 at 14:00
  • 1
    In future, consider waiting longer before selecting an answer. Quick selections can discourage other answers and, imo, are discourteous to those still preparing answers (not me). Moreover, the selected answer is sometimes shown to be incorrect (not here). Many here wait at least a couple of hours before awarding the greenie. Commented Apr 19, 2016 at 15:34

4 Answers 4

2

you can try like this:

 @property_hash.each_with_index {|(k, v), index| @property_hash[k] = line[index]}

Not best way but that will work

Sign up to request clarification or add additional context in comments.

1 Comment

Upvote because this changes the hash in place, which is more efficient than setting @property_hash to a newly-constructed hash. Please remove your last sentence (which is akin to "I'm sure you'll say 'no', but would you go to the dance with me?").
2

My solution assumes that line has the same order every time. So I define another array with the field names, merge the corresponding array elements together and convert the result into a hash.

line = [02, 'Firstname', 'LastName', 5800, 'PL']
fields = @property_hash.keys
# => [:code, :fname, :lname, :basic_sal, :emp_type]    


key_value_pairs = fields.zip(line)
# => [[:code, 2], [:fname, "Firstname"], [:lname, "LastName"], [:basic_sal, 5800], [:emp_type, "PL"]]

@property_hash = Hash[key_value_pairs]
# => {:code=>2, :fname=>"Firstname", :lname=>"LastName", :basic_sal=>5800, :emp_type=>"PL"}

4 Comments

As of Ruby 1.9 and onwards, hash entries are ordered by order of creation, so you can now rely on the order being present and consistent.
@SteveTurczyn: Thanks for the helpful information. I will edit my answer.
fields can be written as @property_hash.keys
@WandMaker: Yes, you're right. With the information of SteveTurczyn I can do so.
1

Memory-wise, it is more efficient to change @property_hash in place rather than setting @property_hash equal to a newly-constructed hash. Here is one way to that:

lc = line.dup
@property_hash.update(@property_hash) { lc.shift }
  #=> { :code => 02,
        :fname => 'Firstname',
        :lname => 'LastName',
        :basic_sal => 5800,
        :emp_type => 'PL' }

This uses the form of Hash#update (aka merge!) that uses a block to determine the value of keys that are present in both hashes being merged, which here is all of the keys.

2 Comments

Nice trick, not sure whether it will be used in real life like this
@Wand, that was my impression when I first saw it, but I've come to rather like it. For one, it returns the updated hash, unlike, for example, h.keys.each { |k| h[k] = lc.shift }.
1

Here is one more way it can be done:

[@property_hash.keys, line].transpose.to_h

1 Comment

More generally, when arrays a and b are the same size, a.zip(b) and [a,b].transpose are interchangeable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.