0

I have hash data (originally in json) and an array of selected hash keys:

jsondata ='{"1":
          {"name": "Tax Exempt"},
       "2":
          {"name": "Tax on Purchases"},
       "3":
          {"name": "Tax on Sales"},
       "4":
          {"name": "Service Tax"}              
        }'
parseddata = JSON.parse(jsondata);    
selectedtax = ["2","3"]

My code maps the keys and returns the value of the hash that exist in the array. Here is the code:

selectedtaxdetails = Array.new
parseddata.map do |key,value|  
  if selectedtax.include? key 
    selectedtaxdetails << value               
  end
end  

Output of selectedtaxdetails is:

[{"name": "Tax on Purchases"},{"name": "Tax on Sales"}] 

How can I improve my code?

8
  • 3
    you should use some underscores: selected_tax_details is easier to read Commented May 21, 2014 at 8:15
  • Your code is invalid. Commented May 21, 2014 at 8:32
  • Is json parsing relevant at all to your question? If not, remove it. Give the hash in Ruby. Give only the relevant parts. Commented May 21, 2014 at 8:38
  • whats wrong with you sawa ? which part of the code is not working! i just ran this in ruby with of course require 'json' and it works. Commented May 21, 2014 at 8:42
  • 1
    @Axil - You missed an opening quote here: selectedtax = ["2",3"] Commented May 21, 2014 at 8:52

2 Answers 2

4

Solution:

You can do (rails):

parseddata.slice(*selectedtax).values

or even simpler (pure ruby):

parseddata.values_at(*selectedtax)

Explanation:

Both slice and values_at methods expect a list of keys. If you just pass an array it will search for values where this array is a key, whcih obviously is not what you want. Instead you can use a splat operator (*). It will take each element of an array and will pass it into a method as a separate argument, which is exactely what we want here.

Update:

To achieve structure: [{"code":"2", "name": "Tax on Purchase"},{"code":"3", "name": "Tax on Sales"}] you can do (rails):

parseddata.slice(*selectedtax).map {|key, value| value.dup.tap {|h| h['code'] = key}}

or with pure ruby:

parseddata.select{|key,_| selectedtax.include? key}.map {|key, value| value.dup.tap {|h| h['code'] = key}}
Sign up to request clarification or add additional context in comments.

7 Comments

This answer would be better if you explained the use of the splat operator.
+1 for values_at
@MikeCampbell - here it is. :)
thanks! works perfectly. got another question, if i wanted to return {"code":"2", "name": "Tax on Purchase"},{"code":"3", "name": "Tax on Sales"}. how do i construct a new structure for the returned array ?
@Axil - This is rails (ActiveSupport core extension) method, I'll update with non-rails code in a second. :)
|
0

The following should do the same in one line

parseddaata.values_at(*selectedtax)

Comments

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.