in reply to How to bucket an Hash

Hello techman2006,

Your question implies that the code shown works correctly. But what happens if you have an odd number of elements in the hash? Running your code with %hash = ( 1 => 'a', 2 => 'b', 3 => 'c', 4 => 'd', 5 => 'e' ) I get:

16:51 >perl 786_SoPW.pl Total keys are 5 $VAR1 = { '1' => 'a', '5' => 'e' }; $VAR1 = { '4' => 'd', '3' => 'c' }; $VAR1 = [ { '1' => 'a', '5' => 'e' }, { '4' => 'd', '3' => 'c' } ]; 16:51 >

which shows that the fifth element is left out altogether.

Anyway, here is my solution, a variation on hdb’s approach which uses the natatime function from List::MoreUtils:

#! perl use strict; use warnings; use Data::Dump qw( pp ); use List::MoreUtils qw( natatime ); my $i = 1; my %hash = map { $i++ => $_ } 'a' .. 'e'; print 'Initial hash: ', pp(\%hash), "\n"; my $it = natatime 2, sort { $a <=> $b } keys %hash; my @array_of_hashes; while (my @keys = $it->()) { my %new_hash = map { ( $_, $hash{$_} ) } @keys; push @array_of_hashes, \%new_hash; } print 'Array of hashes: ', pp(\@array_of_hashes), "\n";

Update: Changed 'a' .. 'j' to 'a' .. 'e', and the first argument to natatime from 4 to 2, to match the output shown.

Output:

16:54 >perl 786_SoPW.pl Initial hash: { 1 => "a", 2 => "b", 3 => "c", 4 => "d", 5 => "e" } Array of hashes: [{ 1 => "a", 2 => "b" }, { 3 => "c", 4 => "d" }, { 5 +=> "e" }] 16:55 >

Hope that helps,

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^2: How to bucket a Hash
by techman2006 (Beadle) on Nov 27, 2013 at 07:29 UTC

    That was a test program and it didn't take care of the all the cases :). Thanks for fixing that issue.

    As I was looking to different solutions which can be used while assigning jobs to multiple threads. As I want a fixed size queue is assigned to each thread. As the job items are present in a HASH, I was looking a method through which this slicing can be done on a faster way as the total keys can be high.

      Why do you want a fixed work unit size for each thread? Given the vagaries of multitasking, some thread is sure to finish a fixed length task before another doing the same size task. Why not just pour all your data into a Thread::Queue and have a pool of workers servicing this queue? If you have a very large amount of data it can also be handy to have a size limited queue, BrowserUK gives a great example here: Re^5: dynamic number of threads based on CPU utilization.

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!