# Q: Only put unique element in a HoL?

#### Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

•  Subject
• Author
• Posted on

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.

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 }, \$element;
}

## Re: Q: Only put unique element in a HoL?

> 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.
>
> 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 }, \$element;
> }

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

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

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

## Re: Q: Only put unique element in a HoL?

* 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 }, \$element;
> }

_;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->++;
}
my %HoL = map { \$_ => [ keys %} ] } 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

## Re: Q: Only put unique element in a HoL?

mpe17@kth.se (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.

Maybe you want a HoH rather than a HoL.

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

\$HoL=();

Xho

--
Usenet Newsgroup Service                        \$9.95/Month 30GB

## Re: Q: Only put unique element in a HoL?

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.
>
> 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)/;

John
--
use Perl;
program
fulfillment

## Re: Q: Only put unique element in a HoL?

Thanks!

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

Regards,
Magnus