Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Until loop / unique

by monkini (Initiate)
on Nov 11, 2013 at 21:29 UTC ( [id://1062057]=perlquestion: print w/replies, xml ) Need Help??

monkini has asked for the wisdom of the Perl Monks concerning the following question:

For each of the five keys I have I'm retrieving the second key and corresponding value from a double hash - then I want to sort those according to value, and if there are any duplicates in 'second' keys, I want to retrieve another one, until all five 'second' keys are unique.

foreach my $k (keys %{$data[$i]}) { #5 keys my ($key, $val) = retrieve_kv($hash{$k}); ### CHECK IF UNIQUE - push to array and sort? ### REDO my ($key, $val) = retrieve_kv($hash{$k}) ### UNTIL ALL 5 ARE UNIQUE }

Any tips on how to structure the inner loop efficiently?

Replies are listed 'Best First'.
Re: Until loop / unique
by oiskuu (Hermit) on Nov 12, 2013 at 00:42 UTC
    So it's a matter of merging hashes? You could use an iterator, perhaps something like the following:
    #! /usr/bin/perl -l my $zoo = { Mountain => { Dragon => 'Deadly', Troll => 'Deadly', Nymph => 'Oread +', Snake => 'Deadly' }, Cave => { Dragon => 'Deadly', Spider => 'Poisonous', Troll => 'Deadl +y', Ogre => 'Deadly' }, Forest => { Elf => 'Dark', Troll => 'Deadly', Nymph => 'Alseid', Spi +der => 'Hairy' }, Lake => { Nymph => 'Naiad', Snake => 'Poisonous', Serpent => 'Deadly +' }, Sea => { Kraken => 'Monstrous', Serpent => 'Monstrous' } }; sub each_uniq { my @refs = @_; my %seen = (); sub { while (@refs) { my @pair = each %{$refs[0]} or shift @refs and next; return @pair unless $seen{$pair[0]}++; } return; } } my $iter = each_uniq(values %$zoo); print join(", ", $iter->()) for 1..5;

    Update. I read the previous questions monkini has asked, and it would appear the problem is largely unrelated to questions asked. From what I gather, he has a number of clusters each with a number of (labelled) points, and distances between points given. The problem apparently is to list the pairs of points in a cluster sorted by their distance, for each cluster separately. If so, the solution is to map clusters to points (HoA), iterate, slice map slice sort the HoH, print.

Re: Until loop / unique
by Laurent_R (Canon) on Nov 11, 2013 at 22:58 UTC

    Maybe you could provide a Data::Dumper output of your structure (or part thereof) to clarify your problem.

      I agree ... I think that we really need to see this thing, in order to comment meaningfully about it and thus answer the OP question.   Nothing less will do in this case.

Re: Until loop / unique
by LanX (Saint) on Nov 11, 2013 at 22:04 UTC
    Sorry, I don't understand what you want...

    Hashes are unsorted in Perl, there is nothing like "second keys".

    Programming is an art of speaking, maybe it helps rephrasing your ideas in proper English?

    -> How do I post a question effectively?

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      oops sorry, I was unclear here. The hash looks like:

      $hash{$key1}{$key2} = $value

      The subroutine 'retrieve_kv' already retrieves the other key and corresponding value, my question is how to put it in the loop, so that the keys retrieved are unique (there can be duplicates). Basically sth like:

      do { my ($key, $val) = retrieve_kv($hash{$k}); } until (ALL 5 KEYS ARE UNIQUE);

        Use List::MoreUtils::uniq().

        use strict; use warnings; use List::MoreUtils qw( uniq ); my %deck; for my $suit (qw( Clubs Hearts Diamonds Spades )) { for my $rank (qw( 2 3 4 5 6 7 8 9 10 J Q K A )) { $deck{$suit}{$rank} = 1; } } $, = " "; $\ = "\n"; # Prints 10 2 3 4 5 6 7 8 9 A J K Q print sort { $a cmp $b } uniq map { keys $deck{$_} } keys %deck;
Re: Until loop / unique
by marinersk (Priest) on Nov 11, 2013 at 22:42 UTC
    Were you thinking of doing this recursively?

    If so I'd consider a count of keys to drive the decision to dive any deeper. Carry the prefix with you as you recurse so you can assemble the full key path before returning it to the calling layer.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1062057]
Approved by keszler
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-19 15:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found