0

I have a hash like this below

h = {a: 1, b: 2, c: 3, d: 4.....z: 26}

now user input 1 then I will fetch first 5 if user input 2 then 6 to next 5 means 6 to 11

How can I acheieve this by a best way

3
  • 1
    You could improve your answer in a couple of ways. 1) h should be a valid Ruby hash (no ....), so readers can cut-and-paste rather than having to construct the hash. Also, .... leaves the impression that you are lazy. 2. If you mean it to be an arbitrary hash (which I assume is the case), you should not have such a regular pattern (:a, :b, :c,... and 1, 2, 3,...) as some readers will interpret your question as referring to that specific hash. Commented Aug 10, 2016 at 7:44
  • 1
    Your question is unclear. Please define what you mean by "best way". Also, what do you mean by "like this"? Is it always that exact hash? What's the pattern that makes the hashes "like" this one? Commented Aug 10, 2016 at 7:47
  • I'm afraid I don't understand this at all: "now user input 1 then I will fetch first 5 if user input 2 then 6 to next 5 means 6 to 11". Could you please edit your question to show specific examples for the different inputs and corresponding outputs? Commented Aug 11, 2016 at 21:35

4 Answers 4

5
h = {a: 1, b: 2, c: 3, d: 4.....z: 26}

user_input = 1

Hash[h.to_a[((user_input - 1) * 5 )..( (user_input * 5) - 1)]]
#=> {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5} 
Sign up to request clarification or add additional context in comments.

Comments

2

I assume the question concerns an arbitrary hash.

Code

Three choices:

#1

def select_em(h, which_block_5)
  select_range = (5*which_block_5 - 4)..(5*which_block_5)
  h.select.with_index(1) { |_,i| select_range.cover?(i) }
end

#2

def select_em(h, which_block_5)
  select_array = Array.new(5*(which_block_5-1),false) +
                 Array.new(5,true) +
                 Array.new(h.size-5*(which_block_5),false)
  h.select { select_array.shift }
end

Note

 select_array = Array.new(5*(which_block_5-1),false) +
                Array.new(5,true) +
                Array.new(26-5*(which_block_5),false)
   #=> [false, false, false, false, false, true, true, true, true, true,
   #    false, false, false, false, false, false, false, false, false,
   #    false, false, false, false, false, false, false] 

#3

def select_em(h, which_block_5)
  start = 5*which_block_5 - 4
  stop  = start + 4
  h.select.with_index(1) { |_,i| (i==start..i==stop) ? true : false }
end

This method uses Ruby's flip-flop operator.

All of these methods use Hash#select (which returns a hash), not Enumerable#select (which returns an array).

Examples

h = {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5, :f=>6, :g=>7, :cat=>"meow",  :dog=>"woof",
     :h=>8, :i=>9, :j=>10, :k=>11, :l=>12, :m=>13, :n=>14, :o=>15,
     :p=>16, :q=>17, :r=>18, :s=>19, :t=>20, :u=>21, :v=>22, :w=>23,
     :x=>24, :y=>25, :z=>26} 

select_em(h, 1)
  #=> {:a=>1, :b=>2, :c=>3, :d=>4, :e=>5} 
select_em(h, 2)
  #=> {:f=>6, :g=>7, :cat=>"meow", :dog=>"woof", :h=>8} 
select_em(h, 3)
  #=> {:i=>9, :j=>10, :k=>11, :l=>12, :m=>13} 
select_em(h, 4)
  #=> {:n=>14, :o=>15, :p=>16, :q=>17, :r=>18} 

Comments

0

Here is what i would do:

char_ary = ('a'..'z').to_a
start_idx = (input - 1) * 5
subary = char_ary.slice(start_idx, 5)
subary.inject({}) do |h, c|
  h[c.to_sym] = char_ary.index(c) + 1
  h
end

This doesn't need a hash to be defined with all the alphabets.

1 Comment

I believe the hash given was just an example. If is was that particular hash, you wouldn't have to do any slicing or selecting, just construct the 5-element hash directly.
-1

So you can simply use slice array function to split out things.

   alphabets = [*('a'..'z')].collect.with_index{ |key,index| { key => index+1  }  } 
   user_input = 1 # Capture user input here. 
   part_of_array = alphabets[( (user_input - 1) * 5 )..( (user_input * 5) - 1)]

Converting into simple one hash use the below code.

part_of_array = eval(alphabets[( (user_input - 1) * 5 )..( (user_input * 5) - 1)].to_s.gsub("{","").gsub("}",""))

Let me know if you have any issues.

3 Comments

This code will generate array with standalone hashes: [{"a"=>1}, {"b"=>2}, {"c"=>3}, {"d"=>4}, {"e"=>5}]
Simple. eval(alphabets[( (user_input - 1) * 5 )..( (user_input * 5) - 1)].to_s.gsub("{","").gsub("}",""))
My comment on @Jagdeep's answer applies to yours as well.

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.