Q: Only put unique element in a HoL?

Discussion in 'Perl Misc' started by Magnus, Mar 8, 2005.

  1. Magnus

    Magnus Guest

    Hi!

    How do I only put unique element into a HoL? I do not want to add
    $element into HoL if it is already there. Here is my program so far,
    but this version adds every element for a $hashkey.

    Thanks in advance!
    Magnus

    while(<>)
    {
    chomp;
    my @line = split(/;/);
    # Set hashkey to $line[1] but only first 10 digits
    my $hashkey = substr($line[1], 0, 9);
    my $element = $line[3];
    push @{ $HoL{$hashkey} }, $element;
    }
    Magnus, Mar 8, 2005
    #1
    1. Advertising

  2. Magnus

    Anno Siegel Guest

    Magnus <> wrote in comp.lang.perl.misc:
    > Hi!
    >
    > How do I only put unique element into a HoL? I do not want to add
    > $element into HoL if it is already there. Here is my program so far,
    > but this version adds every element for a $hashkey.
    >
    > Thanks in advance!
    > Magnus
    >
    > while(<>)
    > {
    > chomp;
    > my @line = split(/;/);
    > # Set hashkey to $line[1] but only first 10 digits
    > my $hashkey = substr($line[1], 0, 9);
    > my $element = $line[3];
    > push @{ $HoL{$hashkey} }, $element;
    > }


    Of course it adds every element, you have done nothing to stop it. Check
    for existence before you push an element:

    push @{ $HoL{$hashkey} }, $element unless
    grep $_ eq $element, @{ $HoL{$hashkey} };

    If the sequence of elements doesn't matter, things can be simplified
    and perhaps sped up by intermediately using the HoL as a hash of hashes:

    while(<>)
    {
    chomp;
    my @line = split(/;/);
    # Set hashkey to $line[1] but only first 10 digits
    my $hashkey = substr($line[1], 0, 9);
    my $element = $line[3];
    $HoL{ $hashkey}->{ $element} = (); # just set the key
    }
    $_ = [ keys %$_] for values %HoL; # rebuild a HoL

    (Code untested)

    Anno
    Anno Siegel, Mar 8, 2005
    #2
    1. Advertising

  3. * Magnus wrote:
    >
    > How do I only put unique element into a HoL? I do not want to add
    > $element into HoL if it is already there. Here is my program so far,
    > but this version adds every element for a $hashkey.
    >
    > while(<>) {
    > chomp;
    > my @line = split(/;/);
    > # Set hashkey to $line[1] but only first 10 digits
    > my $hashkey = substr($line[1], 0, 9);
    > my $element = $line[3];
    > push @{ $HoL{$hashkey} }, $element;
    > }


    If your input looks like

    _;a;_;b
    _;a;_;b

    you'll get

    $HoL = { 'a' => [ 'b', 'b' ] };

    Is that what you mean with "is already there" (the second 'b' shouldn't
    appear in this array)? In this case you could use a HoH -- so there's no
    possibility to generate identical elements.


    my %HoH;
    while ( <> ) {
    chomp;
    my @line = split /;/;
    my $hashkey = substr $line[1], 0, 9;
    $HoH{$hashkey}->{$line[3]}++;
    }
    my %HoL = map { $_ => [ keys %{$HoH{$_}} ] } keys %HoH;


    This last map-statement changes the HoH back to your HoL if desired.

    But your queston is not unambiguous: Consider

    _;a;_;b
    _;c;_;b

    as input. Would you like to add the second 'b' into your HoL, or to
    prevent this because there's already the first 'b' in your HoL (in
    hashkey 'a')? If this is what you want, you can change your keys to
    values and vice versa to ensure that there are no doubled elements.

    regards,
    fabian
    Fabian Pilkowski, Mar 8, 2005
    #3
  4. Magnus

    Guest

    (Magnus) wrote:
    > Hi!
    >
    > How do I only put unique element into a HoL? I do not want to add
    > $element into HoL if it is already there.


    If it is already where?

    Maybe you want a HoH rather than a HoL.

    > push @{ $HoL{$hashkey} }, $element;


    $HoL{$hashkey}{$element}=();

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Mar 8, 2005
    #4
  5. Magnus wrote:
    >
    > How do I only put unique element into a HoL? I do not want to add
    > $element into HoL if it is already there. Here is my program so far,
    > but this version adds every element for a $hashkey.
    >
    > Thanks in advance!
    > Magnus
    >
    > while(<>)
    > {
    > chomp;
    > my @line = split(/;/);
    > # Set hashkey to $line[1] but only first 10 digits

    ^^^^^^^^^^^^^^^^^^^^^^^^

    > my $hashkey = substr($line[1], 0, 9);

    ^
    Then why are you only asking for the first nine characters?

    Perhaps you meant:

    my ( $hashkey ) = $line[1] =~ /^(\d{10})/;




    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Mar 8, 2005
    #5
  6. Magnus

    Magnus Guest

    Thanks!

    A HoH solved my problem. It's great to get help from you guys.

    Regards,
    Magnus
    Magnus, Mar 9, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike
    Replies:
    1
    Views:
    431
  2. ToshiBoy
    Replies:
    6
    Views:
    829
    ToshiBoy
    Aug 12, 2008
  3. beny 18241
    Replies:
    5
    Views:
    98
    Marnen Laibow-Koser
    Dec 20, 2009
  4. Replies:
    5
    Views:
    130
  5. Token Type
    Replies:
    9
    Views:
    339
    Chris Angelico
    Sep 9, 2012
Loading...

Share This Page