Vra

Ek het'n skikking in Perl:

my @my_array = ("one","two","three","two","three");

Hoe kan ek verwyder die duplikate van die skikking?

Was dit nuttig?

Oplossing

Jy kan iets soos dit te doen soos gedemonstreer in perlfaq4 :

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

my @array = qw(one two three two three);
my @filtered = uniq(@array);

print "@filtered\n";

Uitsette:

one two three

As jy wil 'n module te gebruik, probeer die uniq funksie van List::MoreUtils

Ander wenke

Die Perl dokumentasie kom met 'n pragtige versameling van vrae. Jou vraag word dikwels gevra:

% perldoc -q duplicate

Die antwoord, kopieer en plak van die uitset van die opdrag hierbo, blyk onder:

Found in /usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod
 How can I remove duplicate elements from a list or array?
   (contributed by brian d foy)

   Use a hash. When you think the words "unique" or "duplicated", think
   "hash keys".

   If you don't care about the order of the elements, you could just
   create the hash then extract the keys. It's not important how you
   create that hash: just that you use "keys" to get the unique elements.

       my %hash   = map { $_, 1 } @array;
       # or a hash slice: @hash{ @array } = ();
       # or a foreach: $hash{$_} = 1 foreach ( @array );

       my @unique = keys %hash;

   If you want to use a module, try the "uniq" function from
   "List::MoreUtils". In list context it returns the unique elements,
   preserving their order in the list. In scalar context, it returns the
   number of unique elements.

       use List::MoreUtils qw(uniq);

       my @unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 1,2,3,4,5,6,7
       my $unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 7

   You can also go through each element and skip the ones you've seen
   before. Use a hash to keep track. The first time the loop sees an
   element, that element has no key in %Seen. The "next" statement creates
   the key and immediately uses its value, which is "undef", so the loop
   continues to the "push" and increments the value for that key. The next
   time the loop sees that same element, its key exists in the hash and
   the value for that key is true (since it's not 0 or "undef"), so the
   next skips that iteration and the loop goes to the next element.

       my @unique = ();
       my %seen   = ();

       foreach my $elem ( @array )
       {
         next if $seen{ $elem }++;
         push @unique, $elem;
       }

   You can write this more briefly using a grep, which does the same
   thing.

       my %seen = ();
       my @unique = grep { ! $seen{ $_ }++ } @array;

Installeer lys :: MoreUtils van CPAN

Toe ek in jou kode:

use strict;
use warnings;
use List::MoreUtils qw(uniq);

my @dup_list = qw(1 1 1 2 3 4 4);

my @uniq_list = uniq(@dup_list);

My gewone manier om dit te doen is:

my %unique = ();
foreach my $item (@myarray)
{
    $unique{$item} ++;
}
my @myuniquearray = keys %unique;

As jy 'n gemors te gebruik en die items by te voeg aan die hash. Jy het ook die bonus te weet hoeveel keer elke item verskyn in die lys.

kan gedoen word met 'n eenvoudige Perl een sak.

my @in=qw(1 3 4  6 2 4  3 2 6  3 2 3 4 4 3 2 5 5 32 3); #Sample data 
my @out=keys %{{ map{$_=>1}@in}}; # Perform PFM
print join ' ', sort{$a<=>$b} @out;# Print data back out sorted and in order.

Die PFM blok doen dit:

Data in @in gevoer in MAP. MAP bou 'n anonieme hash. Sleutels uit die hash en voed in @out

Die veranderlike @array is die lys met dubbele elemente

%seen=();
@unique = grep { ! $seen{$_} ++ } @array;

Dit laaste een was redelik goed. Ek wil net aanpas dit 'n bietjie:

my @arr;
my @uniqarr;

foreach my $var ( @arr ){
  if ( ! grep( /$var/, @uniqarr ) ){
     push( @uniqarr, $var );
  }
}

Ek dink dit is waarskynlik die mees leesbare manier om dit te doen.

Metode 1: Gebruik 'n hash

logika: 'n hash kan net unieke sleutels het, so Itereer oor skikking, enige waarde toeken aan elke element van skikking, hou element as sleutel van daardie hash. Terugkeer sleutels van die hash, sy jou unieke skikking.

my @unique = keys {map {$_ => 1} @array};

Metode 2: Uitbreiding van metode 1 vir herbruikbaar

Dit is beter om 'n subroutine maak as ons veronderstel is om hierdie funksie te gebruik meer as een keer in ons kode.

sub get_unique {
    my %seen;
    grep !$seen{$_}++, @_;
}
my @unique = get_unique(@array);

Metode 3: Gebruik module List::MoreUtils

use List::MoreUtils qw(uniq);
my @unique = uniq(@array);

Vorige antwoorde pretty much som van die moontlike maniere van die totstandbrenging van hierdie taak.

Egter, ek stel voor'n verandering vir diegene wat nie omgee tel die duplikate, maar doen sorg oor die einde.

my @record = qw( yeah I mean uh right right uh yeah so well right I maybe );
my %record;
print grep !$record{$_} && ++$record{$_}, @record;

Let daarop dat die voorheen voorgestel grep !$seen{$_}++ ... inkremente $seen{$_} voor ontkenning, sodat die inkrement plaasvind, ongeag of dit is reeds %seen of nie.Die bo, egter, kort-stroombane wanneer $record{$_} is waar, die verlaat van wat is die gehoor keer " uit die %record'.

Jy kan ook gaan vir hierdie belaglikheid, wat neem voordeel van autovivification en die bestaan van'n hash sleutels:

...
grep !(exists $record{$_} || undef $record{$_}), @record;

Dit, egter, kan lei tot'n paar verwarring.

En as jy nie omgee nie om of dubbele telling, kan jy vir'n ander hack met behulp van hash snye en die truuk wat ek nou net genoem het:

...
undef @record{@record};
keys %record; # your record, now probably scrambled but at least deduped

Probeer hierdie, lyk die UNIQ funksie moet 'n gesorteerde lys om behoorlik te werk.

use strict;

# Helper function to remove duplicates in a list.
sub uniq {
  my %seen;
  grep !$seen{$_}++, @_;
}

my @teststrings = ("one", "two", "three", "one");

my @filtered = uniq @teststrings;
print "uniq: @filtered\n";
my @sorted = sort @teststrings;
print "sort: @sorted\n";
my @sortedfiltered = uniq sort @teststrings;
print "uniq sort : @sortedfiltered\n";

Die gebruik van konsep van unieke hash sleutels:

my @array  = ("a","b","c","b","a","d","c","a","d");
my %hash   = map { $_ => 1 } @array;
my @unique = keys %hash;
print "@unique","\n";

Uitgawe: 'n c b d

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top