2

I have multiple values for each key in the hash. Here, I print the values of each key

print "$var:",join ',',@{$hash{$var}},"\n";

Output of the above print statement is:

ABC:1,2,3,1,4,2,
DEF:9,3,4,5,3,5,

Now, I want to remove duplicates in the values. The desired output is,

ABC:1,2,3,4
DEF:9,3,4,5

Can someone help me in this?

Thanks

0

4 Answers 4

3

Personally, I like how List::MoreUtils's uniq handles this. The subroutine is quite simple, and can be used as-is, or through the module.

my %seen;
my @dedupe = grep { not $seen{$_}++ } @{$hash{$var}};

The subroutine from the module looks like this:

sub uniq (@) {
    my %seen = ();
    grep { not $seen{$_}++ } @_;
}

This code preserves the initial order of the list.

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

4 Comments

Hmm, do you use defined types of variables in function header all time?
If you mean do I personally use prototypes, then the answer is no. That sub is copy pasted from the module. I considered removing it, because as a general rule prototypes should not be recommended to beginners, but since it was basically a quote, I left it as it was.
yeah, i heard about it. but i don't understand, why people use it in CPAN modules.
Well, they do have a purpose. On the other hand, many people use them for no good reasons.
3

Using List::MoreUtils::uniq:

@$_ = uniq @$_ foreach values %hash;

Comments

2

That it's in a hash is irrelevant. What you're wanting to do is dedupe the values in an array.

Look at the uniq() function in List::MoreUtils module http://search.cpan.org/dist/List-MoreUtils/

You can also do it yourself like so:

my %h = map {($_,1)} @array_with_dupes;
my @deduped_array = keys %h;

This is all covered extensively in the Perl FAQ under "Data: Arrays".

2 Comments

The do-it-yourself solution does not preserve the initial order of the elements.
That wasn't specified as a requirement. I can see how you'd infer it, though.
2

If you are trying to remove duplicate values from an array you can use this

#!/usr/bin/perl -w
use strict;
my @array = ('a','b','c','c','e');
my %hash = map { $_ => 1 } @array;
my @out = keys %hash;
printf("%s",join(',',@out));

1 Comment

This method does not preserve the initial order of your list.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.