-3

I am using Active Perl 5.20.2.

uniq function when applied on an array returns the full array with duplicate values. Please refer to the code below and kindly let know any issues with it or any other way to get the unique values from a list.

use List::MoreUtils qw(uniq);

print "@$_\n" for @urls;

@unique1 = uniq(@urls);

print "@$_\n" for @unique1;

Output

urls array values - 6 6 6 6 6 6 6 6 6 6 6 6

@unique 1 - 6 6 6 6 6 6 6 6 6 6 6 6


I have even used the functions below with no luck — they're available from searching Google.

*sub uniq{
 my %seen;
 grep !$seen{$_}++, @_;
}
foreach my $value (@urls) {
if (!$seen{$value} ) 
{
push @unique1, $value;
$seen{$value} = 1;
}*
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
chint
  • 47
  • 1
  • 8
  • 2
    It would be helpful for you to provide a complete sample program that demonstrates your problem. Could you edit your sample code to show how you're initializing `@urls`? – Kenster May 30 '15 at 13:37
  • Looks like `@urls` is a list with the value "6 6 6 6 6 6 6 6 6 6 6 6" otherwise there would be newlines between each `6`... – Kusalananda May 30 '15 at 15:28
  • 1
    "Uniq function in Perl not working" ... yes it is. Seriously ... Other people have used it. Do you think such a problem went unnoticed? Yes, occasionally, [there are bugs in tools in widespread use](https://connect.microsoft.com/VisualStudio/feedback/details/1304939), but, more often than not, [the bug is in your code](http://c2.com/cgi/wiki?CompilerBug). – Sinan Ünür May 30 '15 at 22:53

2 Answers2

2

What you appear to have in your @urls array is twelve anonymous arrays that contain the single element 6. In other words it looks like this

my @urls = ( [6], [6], [6], [6], [6], [6], [6], [6], [6], [6], [6], [6] );

What uniq does is to remove superfluous elements from the list if their string value is the same as that of a preceding element. The string value of an array reference is something like ARRAY(0x1f6c6e4)

If your array contained twelve references to the same anonymous array then uniq would have removed all but one. But it looks like you have twelve distinct arrays that just happen to contain the same value and uniq won't notice that

It is hard to know how to help as, because [6] isn't much like a URL, the real data in your array is probably very different. Perhaps you have a bug in your code, or perhaps you really need to compare the contents of all the subsidiary arrays, but we cannot tell

I suggest that you post another question that shows a dump (using Data::Dump) of your @urls array and describes what you want to do with it. It would also help you to read How to Ask so that those of us who would help you aren't left with so many doubts about the real situation

Community
  • 1
  • 1
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 1
    It's either that or he has one single value, "6 6 6 6 6 6 6 6 6 6 6 6". This is more likely since he, in the first loop, print each element of the array with a trailing newline, and there's only one newline in the output. – Kusalananda May 30 '15 at 15:27
  • 1
    @Kusalananda: Yes. That would be a single anonymous array though `[ "6 6 6 6 6 6 6 6 6 6 6 6" ]`. Strange – Borodin May 30 '15 at 16:00
1

Please learn how to provide an MCVE (How to create a Minimal, Complete, and Verifiable Example?) or SSCCE (Short, Self-Contained, Correct Example) — two names and links for the same basic idea.

The uniq function does work. Here is a completed, marginally fixed variant of your code converted into an MCVE.

listuniq.pl

#!/usr/bin/env perl
use strict;        # Always use these
use warnings;

my @urls = ( 6, 6, 6, 6, 6, 6, 6, 6, 6 );

use List::MoreUtils qw(uniq);

print "Before:\n";
print "$_\n" for @urls;    # Note the @ is missing

my @unique1 = uniq(@urls);

print "After:\n";
print "$_\n" for @unique1; # Note the @ is missing

@urls = ();

push @urls, "http://www.google.com/", "http://www.yahoo.com/" for (1..6);

print "Before:\n";
print "$_\n" for @urls;

@unique1 = uniq(@urls);

print "After:\n";
print "$_\n" for @unique1;

The @ symbols in print "@$_\n" lead to complaints because of the use strict;. Unless you were really planning something very fancy, you need to (a) use use strict; and use warnings; and (b) pay heed to them.

Example run

$ perl listuniq.pl | so
Before:
6
6
6
6
6
6
6
6
6
After:
6
Before:
http://www.google.com/
http://www.yahoo.com/
http://www.google.com/
http://www.yahoo.com/
http://www.google.com/
http://www.yahoo.com/
http://www.google.com/
http://www.yahoo.com/
http://www.google.com/
http://www.yahoo.com/
http://www.google.com/
http://www.yahoo.com/
After:
http://www.google.com/
http://www.yahoo.com/
$

Other possibilities

This being Perl, TMTOWTDI — There's More Than One Way To Do It. That includes more than one way of writing code that produces unexpected results — see the other answer and commentary to the other answer for other possible ways to write code that gives confusing results. Because you've not provided an MCVE, it is hard — essentially futile — for us to guess which option you've taken to get the unexpected result. You will always improve your chances of getting the most relevant answer on SO (or any similar site) by providing a question which includes the minimal code necessary to reproduce the result you see.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks Jonathan. I would take care of your all comments going forward. your code works. i had developed another workaround which also is working. – chint May 31 '15 at 14:45