0

I have a hash which contains a list of array and i have to get a unique list from that array . But when i am trying to id i am not getting any error or the unique list.

NOTE : I don't want to use any module.

Below is the sample structure of my hash which has the array :

'15445' => { 'str' => {
                        'TOKEN' => [
                           'HC',
                           'HC',
                           'HC',
                           'HC',
                           'HC',
                           'HC'
                            ]
                }
        }

How i am tying to get a unique list of values from the array TOKEN

foreach my $id (keys %$client) {
    my @unique_srp_id;
    @unique_srp_id = uniq($hash->{$id}->{str}->{TOKEN});
    print @unique_srp_id;
}

sub uniq {
    my %seen;
    grep !$seen{$_}++, @_;
}

Can anyone suggest me what wrong i am doing here.

3
  • 1
    Consider passing references (for arrays/hashes) instead of flat lists Commented Feb 11, 2019 at 21:39
  • @zdim, hmm... Taking an arbitrary number of scalars is far more useful for uniq. Commented Feb 12, 2019 at 1:46
  • @ikegami As a ("far") more common use case (a handful of scalars to clean up)? Right, good point. I just get all itchy when I see multi-valued variables passed around subs freely, for fear of stack abuse or unintended flattening (and out of habits from elsewhere I guess). Commented Feb 13, 2019 at 20:18

2 Answers 2

4

You are passing an array reference containing the values to the function, but the function is expecting the values directly in @_.

my @unique = uniq(@{$hash->{$id}{str}{TOKEN}});

On Perl 5.24+, you can use postderef to make this look a bit nicer (maybe?)

my @unique = uniq($hash->{$id}{str}{TOKEN}->@*)

On Perl 5.26+, the core version of List::Util is new enough (1.45) to contain the uniq function and it will be faster than your pure-perl version and also handle undef values distinctly.

Sign up to request clarification or add additional context in comments.

Comments

2

uniq expects a list but $hash->{$id}->{str}->{TOKEN} is an array reference (a single element). Either pass an array to uniq

 uniq(@{$hash->{$id}{str}{TOKEN}})

or write uniq to expect an array reference

sub uniq {
    my %seen;
    grep !$seen{$_}++, @{$_[0]};
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.