
Zhris
Enthusiast
Oct 7, 2013, 3:01 PM
Post #9 of 9
(4544 views)
|
2teez The solution given was in respect to the dataset shown by the OP. Although the OP described yielding { "dog" => [k,l], "cat" => j}, their code actually yields { "dog" => [k,l], "cat" => [j]}. This led to which output is best as oppose to which is right, after all the OP didn't suggest their code doesn't work the way they would like. I found this of interest, since I commonly face this "dilemma". If there is alot of data and mostly single values / only one or two multiple values then I might use a combination of arrays and strings, since in this case it would be inefficient to treat every value as an array. If the other way round, then I would probably use all arrays, since it wouldn't be much harm to treat the one or two single values as an array. With a small dataset, this isn't of concern.
2teez but why would I want to "grep" for every value You are right, Bill's approach is not the best, but fulfills the OP's suggestion "maybe using grep" and provides "a different approach". Your approach is very nicely thought out, and is probably the most ideal. My personal preference would be; a while loop is more suitable over a for loop in this case; I prefer to read if statements at the end of lines where possible; I love to use loop controls...
my %hash2; while (my ($key, $val) = each %hash1) { if (exists $hash2{$val}) { $hash2{$val} = [ $hash2{$val} ] if (!ref $hash2{$val}); push @{$hash2{$val}}, $key; next; } $hash2{$val} = $key; } print Dumper \%hash2; If all arrays are acceptable, it can be done in 1 line...
my %hash2; push @{$hash2{$hash1{$_}}}, $_ for (keys %hash1); print Dumper \%hash2; Chris
|