From: Robert Klemme Date: 2004-08-17T17:21:01+09:00 Subject: Re: Q: Shifting a hash anf and array "Martin DeMello" schrieb im Newsbeitrag news:u_gUc.122944$M95.4319@pd7tw1no... > Meino Christian Cramer wrote: > > > > Contents of the array before the trick: > > > > 1 2 3 4 5 6 7 8 9 0 index > > A B C D E F G H I J contents > > > > (execute *trick*) > > > > Contents of the array after the trick: > > > > 1 2 3 4 5 6 7 8 9 0 index > > J A B C D E F G H I contents > > array.unshift(array.pop) or array.push(array.shift) for the other direction. > > And now the shift of an hash: > > > > Contents of the hash before the trick: > > > > A B C D E F G H I J key > > 1 2 3 4 5 6 7 8 9 0 value > > > > (execute *trick*) > > > > Contents of the hash after the trick: > > > > A B C D E F G H I J key > > 0 1 2 3 4 5 6 7 8 9 value > > > > Both are very similiar. > > Not really :) Hashes are inherently unordered, so the concept of a > rotation is a bit trickier. This works on the assumption that > Hash#values returns values in positions corresponding to the keys in > Hash#keys... > > class Array > def rot1 > unshift(pop) > end > end > > Hash[*(hash.keys.rot1.zip(hash.values.rot1).flatten)] Hm, IMHO there is one "rot1" too much: you're rotating keys *and* values while you should only rotate one of them. Otherwise I figure the result will be the same as the original hash... :-) The other drawback of your solution is that it relys on #keys and #values returning elements in matching order, i.e., if you zip both you get the same hash. Although that might work it makes me feel a bit wary because AFAIK it's not a guaranteed property of Hash (and I wouldn't want to rely on it). This might even change over time if the Hash implementation was changed for any reasons. How about these one liners, that avoids the problem: h = {0=>"a", 1=>"b", 2=>"c"} # put rotated in h2 (h2={}).send(:[]=, *h.sort.inject {|(k1,v1),(k2,v2)| h2[k1]=v2; [k2, v1]}) # rotate inplace h.send(:[]=, *h.sort.inject {|(k1,v1),(k2,v2)| h[k1]=v2; [k2, v1]}) :-) Note: you can omit the sort in the first example, but IMHO an order should be imposed on keys. Otherwise the rotation does not make much sense IMHO. You can omit the sort in the second example, too, which seems to work because the set of keys of the hash doesn't change. But this seems a bit hackish to me, too. You can substitute "sort" by "dup" though. Kind regards robert PS: Enumerable#inject is cool. ;-)