जवाबों:
आप कुछ ऐसा कर सकते हैं जैसा कि perlfaq4 में दिखाया गया है :
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
my @array = qw(one two three two three);
my @filtered = uniq(@array);
print "@filtered\n";
आउटपुट:
one two three
यदि आप एक मॉड्यूल का उपयोग करना चाहते हैं, तो uniq
फ़ंक्शन से प्रयास करेंList::MoreUtils
my
इस दायरे में है, इसलिए यह ठीक है। कहा जा रहा है, संभवतः एक अधिक वर्णनात्मक चर नाम चुना जा सकता है।
$::a
और $::b
, यह नहीं होगा?
sub uniq { my %seen; grep !$seen{$_}++, @_ }
यह एक बेहतर कार्यान्वयन है क्योंकि यह बिना किसी मूल्य के आदेश को संरक्षित करता है। या इससे भी बेहतर, सूची :: MoreUtils से एक का उपयोग करें।
पर्ल दस्तावेज़ीकरण FAQs का एक अच्छा संग्रह के साथ आता है। आपका प्रश्न अक्सर पूछा जाता है:
% perldoc -q duplicate
ऊपर दिए गए कमांड के आउटपुट से उत्तर, कॉपी और पेस्ट किया गया है:
/Usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod में मिला मैं सूची या सरणी से डुप्लिकेट तत्वों को कैसे निकाल सकता / सकती हूं? (ब्रायन डी फ़ो द्वारा योगदान दिया गया) एक हैश का उपयोग करें। जब आप "अद्वितीय" या "डुप्लिकेट" शब्द सोचते हैं, तो सोचें "हैश कीज़"। यदि आप तत्वों के आदेश की परवाह नहीं करते हैं, तो आप बस कर सकते हैं हैश बनाएँ तो चाबियाँ निकालें। यह महत्वपूर्ण नहीं है कि आप कैसे हैं उस हैश का निर्माण करें: अद्वितीय तत्वों को प्राप्त करने के लिए बस "कुंजी" का उपयोग करें। मेरा% हैश = नक्शा {$ _, 1} @ ऐरे; # या हैश स्लाइस: @ हश {@ हर्रे} = (); # या एक फॉर्च्यूनर: $ हैश {$ _} = 1 फॉर्च्यू (@ ऐरे); my @unique = चाबियाँ% हैश; यदि आप एक मॉड्यूल का उपयोग करना चाहते हैं, तो "यूनीक" फ़ंक्शन से प्रयास करें "सूची :: MoreUtils"। सूची के संदर्भ में यह अद्वितीय तत्वों को लौटाता है, सूची में उनके आदेश को संरक्षित करना। स्केलर के संदर्भ में, यह लौटाता है अद्वितीय तत्वों की संख्या। उपयोग सूची :: MoreUtils qw (uniq); my @unique = uniq (1, 2, 3, 4, 4, 5, 6, 5, 7); # 1,2,3,4,5,6,7 मेरे $ अद्वितीय = यूनीक (1, 2, 3, 4, 4, 5, 6, 5, 7); # 7 आप प्रत्येक तत्व के माध्यम से भी जा सकते हैं और जो आपने देखा है उसे छोड़ सकते हैं इससे पहले। ट्रैक रखने के लिए हैश का उपयोग करें। पहली बार लूप ए देखता है तत्व, उस तत्व की% सीन में कोई कुंजी नहीं है। "अगला" कथन बनाता है कुंजी और तुरंत इसके मूल्य का उपयोग करता है, जो "अपरिभाषित" है, इसलिए लूप "पुश" के लिए जारी है और उस कुंजी के लिए मूल्य बढ़ाता है। अगला जिस समय लूप उसी तत्व को देखता है, उसकी कुंजी हैश और में मौजूद होती है उस कुंजी का मान सत्य है (चूंकि यह 0 या "अपरिभाषित" नहीं है), इसलिए अगला स्काइप कि पुनरावृत्ति और लूप अगले तत्व पर जाता है। my @unique = (); मेरा% देखा = (); मेरे $ ग्यारह (@ ऐरे) पर पहुंचें { अगले अगर $ {$ हाथी} ++ देखा; पुश @ यूनीक, $ एलएम; } आप इसे संक्षिप्त रूप से एक grep का उपयोग करके लिख सकते हैं, जो ऐसा ही करता है चीज़। मेरा% देखा = (); my @unique = grep {! $ देखा गया {$ _} ++} @ ऐरे;
सूची स्थापित करें :: CPAN से MoreUtils
फिर अपने कोड में:
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);
@dup_list
अंदर होना चाहिए uniq
, नहीं@dups
ऐसा करने का मेरा सामान्य तरीका है:
my %unique = ();
foreach my $item (@myarray)
{
$unique{$item} ++;
}
my @myuniquearray = keys %unique;
यदि आप हैश का उपयोग करते हैं और हैश में आइटम जोड़ते हैं। आपके पास यह जानने का भी बोनस है कि सूची में प्रत्येक आइटम कितनी बार दिखाई देता है।
एक साधारण पर्ल एक लाइनर के साथ किया जा सकता है।
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.
PFM ब्लॉक ऐसा करता है:
@In में डेटा MAP में फीड किया जाता है। MAP एक अनाम हैश बनाता है। कीज़ को हैश से निकाला जाता है और @ आउट में फीड किया जाता है
लॉजिक: एक हैश में केवल अनूठी कुंजी हो सकती है, इसलिए सरणी पर पुनरावृति, उस हैश की कुंजी के रूप में तत्व रखते हुए, सरणी के प्रत्येक तत्व को कोई भी मान असाइन करें। हैश की वापसी कुंजी, अपने अद्वितीय सरणी।
my @unique = keys {map {$_ => 1} @array};
यदि हम अपने कोड में कई बार इस कार्यक्षमता का उपयोग करने वाले हैं तो सबरूटीन बनाना बेहतर है।
sub get_unique {
my %seen;
grep !$seen{$_}++, @_;
}
my @unique = get_unique(@array);
List::MoreUtils
use List::MoreUtils qw(uniq);
my @unique = uniq(@array);
पिछले जवाब बहुत ज्यादा इस कार्य को पूरा करने के संभावित तरीकों को संक्षेप में प्रस्तुत करते हैं।
हालांकि, मैं उन लोगों के लिए एक संशोधन का सुझाव देता हूं जो डुप्लिकेट की गिनती के बारे में परवाह नहीं करते हैं, लेकिन आदेश के बारे में परवाह करते हैं ।
my @record = qw( yeah I mean uh right right uh yeah so well right I maybe );
my %record;
print grep !$record{$_} && ++$record{$_}, @record;
ध्यान दें कि पहले सुझाए गए grep !$seen{$_}++ ...
वेतन वृद्धि $seen{$_}
को नकारने से पहले, इसलिए वेतन वृद्धि होती है चाहे वह पहले से हो %seen
या नहीं। हालांकि, ऊपर, शॉर्ट-सर्किट जब $record{$_}
सच होता है, तो जो एक बार 'बंद' सुना जाता है उसे छोड़ देता है %record
।
आप इस हास्यास्पदता के लिए भी जा सकते हैं, जो ऑटिविसिफिकेशन और हैश कीज़ के अस्तित्व का लाभ उठाता है:
...
grep !(exists $record{$_} || undef $record{$_}), @record;
हालाँकि, इससे कुछ भ्रम हो सकता है।
और अगर आप न तो ऑर्डर या डुप्लिकेट गिनती के बारे में परवाह करते हैं, तो आप हैश स्लाइस और मेरे द्वारा बताए गए ट्रिक का उपयोग करके एक और हैक के लिए कर सकते हैं:
...
undef @record{@record};
keys %record; # your record, now probably scrambled but at least deduped
sub uniq{ my %seen; undef @seen{@_}; keys %seen; }
नीट।
यह कोशिश करो, लगता है कि uniq फ़ंक्शन को ठीक से काम करने के लिए एक क्रमबद्ध सूची की आवश्यकता है।
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";
अद्वितीय हैश कुंजी की अवधारणा का उपयोग करना:
my @array = ("a","b","c","b","a","d","c","a","d");
my %hash = map { $_ => 1 } @array;
my @unique = keys %hash;
print "@unique","\n";
आउटपुट: acbd