B Seven
B Seven

Reputation: 45941

How to iterate over part of a hash in Ruby?

h = Hash.new
(1..100).each { |v| h.store(v * 2, v*v) }

What is the best way to iterate over a given part of the hash without using the keys? For example, from element 10 to element 20? Using Ruby 1.9.3.

EDIT - In response to Dave's comment:
Originally I wanted to access the data through keys (hence the hash). But I also want to iterate by element number. BTW, each element is a hash.

So, what is the best way to design a hash of hashes or array of hashes that can be iterated by element number or accessed by key? The data looks like the following. There are missing dates.

6/23/2011 -> 5, 6, 8, 3, 6
6/26/2011 -> 6, 8, 4, 8, 5
6/27/2011 -> 8, 4, 3, 2, 7

Upvotes: 1

Views: 2287

Answers (4)

Darshan Rivka Whittle
Darshan Rivka Whittle

Reputation: 34051

If I understand what you're asking for, you can iterate over a portion of your hash as follows. This gives you the 1001st through 2000th values:

h.keys[1000..1999].each do |key|
    # Do something with h[key]
end

Upvotes: 4

steenslag
steenslag

Reputation: 80085

h = Hash.new
(1..100).each { |v| h.store(v * 2, v*v) }

#for an array of arrays
h.drop(9).take(10) #plus an optional block
#if the slice must be a hash:
slice = Hash[h.drop(9).take(10)]

But if this is an often repeating operation you might be better off using a database.

Upvotes: 1

Andrew Marshall
Andrew Marshall

Reputation: 97004

Convert it to an array, then slice it:

h.to_a[10..20].each { |k, v| do_stuff }

Note that before Ruby 1.9, the order of elements in a hash are not guaranteed, so this will not necessarily work as you expect.

Alternatively, you could use each_with_index and skip over the unwanted elements:

h.each_with_index do |(k, v), i|
  next unless (10..20).include?(i)
  # do stuff
end

Upvotes: 1

vlain
vlain

Reputation: 712

I think you better use Array for that (Hash in Ruby 1.9.3 are ordered but the access method is the keys). So:

a = h.values
# or
a = h.to_a

Upvotes: 1

Related Questions