পার্লের অ্যারে থেকে আমি সদৃশ আইটেমগুলি কীভাবে সরিয়ে ফেলব?


156

পার্লে আমার একটি অ্যারে রয়েছে:

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

অ্যারে থেকে সদৃশগুলি আমি কীভাবে সরিয়ে ফেলব?

উত্তর:


168

পেরফাকাক 4-তে প্রদর্শিত হিসাবে আপনি এর মতো কিছু করতে পারেন :

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


28
দয়া করে $ a বা $ b উদাহরণগুলিতে ব্যবহার করবেন না কারণ সেগুলি () এর যাদু গ্লোবালগুলি রয়েছে
szabgab

2
এটি myএই সুযোগে একটি যুক্তিযুক্ত, তাই এটি ঠিক আছে। বলা হচ্ছে, সম্ভবত আরও বর্ণনামূলক পরিবর্তনশীল নামটি বেছে নেওয়া যেতে পারে।
প্রকাশিত

2
@ প্রিমিয়েন্ট হ্যাঁ, তবে আপনি যদি এই ফাংশনটিতে বাছাই করা যোগ করেন তবে তা ট্রাম্প হবে $::aএবং $::b, তাই না?
ভোলআরন

5
@ ব্রায়ানভেনডেনবার্গ ১৯৮7 সালের বিশ্বের আপনাকে স্বাগতম - যখন এটি তৈরি করা হয়েছিল - এবং পার্লের প্রায় 100% ব্যাকওয়ার্ডের সামঞ্জস্যতা - তাই এটি নির্মূল করা যায় না।
szabgab

18
sub uniq { my %seen; grep !$seen{$_}++, @_ }এটি কোনও ব্যয় ছাড়াই অর্ডার সংরক্ষণ করে এটি একটি ভাল বাস্তবায়ন। বা আরও ভাল, তালিকা :: MoreUtils থেকে একটি ব্যবহার করুন।
ইকেগামি

120

পার্ল ডকুমেন্টেশন এফএকিউগুলির একটি দুর্দান্ত সংগ্রহ নিয়ে আসে। আপনার প্রশ্ন প্রায়শই জিজ্ঞাসা করা হয়:

% perldoc -q duplicate

উপরের কমান্ডের আউটপুট থেকে উত্তর, অনুলিপি এবং আটকানো নীচে প্রদর্শিত হবে:

/Usr/local/lib/perl5/5.10.0/pods/perlfaq4.pod এ পাওয়া গেছে
 আমি কীভাবে একটি তালিকা বা অ্যারে থেকে সদৃশ উপাদানগুলি সরিয়ে ফেলতে পারি?
   (ব্রায়ান ডি ফোয়াই অবদান)

   একটি হ্যাশ ব্যবহার করুন। আপনি যখন "অনন্য" বা "সদৃশ" শব্দগুলি মনে করেন, তখন ভাবুন
   "হ্যাশ কী"।

   আপনি যদি উপাদানগুলির ক্রম সম্পর্কে চিন্তা না করেন তবে আপনি ঠিক করতে পারেন
   হ্যাশ তৈরি করুন তারপরে কীগুলি বের করুন। কীভাবে আপনি তা গুরুত্বপূর্ণ নয়
   সেই হ্যাশটি তৈরি করুন: অনন্য উপাদানগুলি পেতে আপনি "কী" ব্যবহার করেন।

       আমার% হ্যাশ = মানচিত্র {$ _, 1} @ অ্যারে;
       # বা একটি হ্যাশ স্লাইস: @ হ্যাশ {@ অ্যারে} = ();
       # বা একটি ভবিষ্যদ্বাণী: $ হ্যাশ {$ _} = 1 ফোরচ (@ অ্যারে);

       আমার @ ইউনিক = কীগুলি% হ্যাশ;

   আপনি যদি কোনও মডিউল ব্যবহার করতে চান তবে "ইউনিিক" ফাংশনটি ব্যবহার করে দেখুন
   "তালিকা :: MoreUtils"। তালিকার প্রসঙ্গে এটি অনন্য উপাদানগুলি প্রদান করে,
   তালিকায় তাদের অর্ডার সংরক্ষণ করা। স্কেলার প্রসঙ্গে, এটি ফেরত দেয়
   অনন্য উপাদান সংখ্যা।

       ব্যবহারের তালিকা :: MoreUtils qw (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 বা "অপরিশোধিত" নয়) তাই
   পরবর্তী পুনরুক্তি যে পুনরাবৃত্তি এবং লুপ পরবর্তী উপাদান যায়।

       আমার @ ইউনিক = ();
       আমার% দেখা = ();

       আমার $ এলেম (@ অ্যারে) পূর্বাভাস
       {
         পরবর্তী যদি $ দেখা {$ এলেম} ++;
         @ ইউনিক, $ এলেম;
       }

   আপনি গ্রেপ ব্যবহার করে এটি আরও সংক্ষেপে লিখতে পারেন, এটি একই কাজ করে
   জিনিস।

       আমার% দেখা = ();
       আমার @ ইউনিক = গ্রেপ {! $ {_} ++} @ অ্যারে দেখেছে;


17
জন আমে ইন জন চুরি করে মাহ রেপ!
ব্রায়ান ডি বন্ধু

5
আমি মনে করি আসলে প্রশ্নটি দেখার জন্য আপনার বোনাস পয়েন্ট পাওয়া উচিত।
ব্র্যাড গিলবার্ট

2
আমি পছন্দ করি যে সেরা উত্তরটি 95% অনুলিপি-পেস্ট এবং 3 টি ওসির বাক্য। পুরোপুরি স্পষ্ট করা জন্য, এই হল সর্বোত্তম উত্তর; আমি ঠিক যে ঘটনাটি মজাদার খুঁজছি।
পার্থিয়ান শট

70

ইনস্টল তালিকা :: সিপিএএন থেকে আরও ইউটিলিটিস

তারপরে আপনার কোডে:

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);

4
তালিকা: মোর ইউটিসগুলি ডাব্লু / পার্ল কিন্ডা বান্ডিল নয় এটি ব্যবহার করে প্রকল্পগুলির বহনযোগ্যতার ক্ষতি করে :( (আমি একটার জন্য করব না))
yPhil

3
@Ranguard: @dup_listভিতরে হওয়া উচিত uniqকল না,@dups
incutonez

@ ইয়াসিনফিলিপ সিপিএএন এমন একটি জিনিস যা পার্লকে যতটা শক্তিশালী এবং দুর্দান্ত করে তোলে। আপনি যদি কেবলমাত্র মডিউলগুলির উপর ভিত্তি করে আপনার প্রকল্পগুলি লিখছেন তবে আপনি সম্ভবত আপনার কোডটিতে একটি বিশাল সীমা রাখছেন, সম্ভবত রাইলি কোড যুক্ত যা কিছু মডিউলগুলি ব্যবহার না করে কেবল আরও ভাল করার চেষ্টা করে। এছাড়াও, মূল মডিউলগুলি কোনও কিছুর গ্যারান্টি দেয় না, কারণ বিভিন্ন পার্ল সংস্করণগুলি বিতরণ থেকে মূল মডিউলগুলি যুক্ত করতে বা মুছে ফেলতে পারে, সুতরাং বহনযোগ্যতা এখনও তার উপর নির্ভর করে।
ফ্রান্সিসকো জারাবোজো

24

আমার এটি করার স্বাভাবিক উপায় হ'ল:

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

যদি আপনি একটি হ্যাশ ব্যবহার করেন এবং আইটেমগুলিকে হ্যাশ যুক্ত করুন। প্রতিটি আইটেমি তালিকায় কতবার উপস্থিত হয় তা জানার বোনাস আপনারও রয়েছে।


2
এটির যদি আপনার প্রয়োজন হয় তবে মূল ক্রমটি সংরক্ষণ না করার ক্ষতি রয়েছে।
নাথান ফেলম্যান

লুপের পরিবর্তে স্লাইসগুলি ব্যবহার করা ভাল foreach:@unique{@myarray}=()
কেবলমাত্র

8

পরিবর্তনশীল @array হ'ল সদৃশ উপাদানগুলির সাথে তালিকা

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

7

একটি সাধারণ পার্ল ওয়ান লাইনার দিয়ে করা যায়।

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.

পিএফএম ব্লক এটি করে:

@ ইন থাকা ডেটা এমএপিতে সরবরাহ করা হয়। এমএপি একটি বেনামে হ্যাশ তৈরি করে। কীগুলি হ্যাশ থেকে বের করা হয় এবং @ আউটতে ফিড করা হয়


4

শেষটি বেশ ভাল ছিল। আমি শুধু এটি একটি সামান্য tweak চাই:

my @arr;
my @uniqarr;

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

আমি মনে করি এটি সম্ভবত এটি সবচেয়ে পাঠযোগ্য way


4

পদ্ধতি 1: একটি হ্যাশ ব্যবহার করুন

যুক্তি: একটি হ্যাশের কেবলমাত্র অনন্য কী থাকতে পারে, সুতরাং অ্যারের উপরে পুনরাবৃত্তি করুন, অ্যারের প্রতিটি উপাদানকে কোনও মান নির্ধারণ করুন, উপাদানটিকে হ্যাশটির কী হিসাবে রাখবেন। হ্যাশটির কীগুলি রিটার্ন করুন এটি আপনার অনন্য অ্যারে।

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

পদ্ধতি 2: পুনঃব্যবহারযোগ্যতার জন্য পদ্ধতি 1 এর সম্প্রসারণ

আমাদের কোডে একাধিকবার এই কার্যকারিতাটি ব্যবহার করার কথা যদি মনে করা হয় তবে সাব্রোটিন তৈরি করা ভাল।

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

পদ্ধতি 3: মডিউলটি ব্যবহার করুন List::MoreUtils

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

1

পূর্ববর্তী উত্তরগুলি এই কার্য সম্পাদনের সম্ভাব্য উপায়গুলির সংক্ষিপ্ত বিবরণ দেয়।

যাইহোক, আমি যারা জন্য একটি পরিবর্তন সুপারিশ না যত্ন সম্পর্কে গণনা সদৃশ কিন্তু কি অর্ডার যত্নশীল।

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; } ঝরঝরে।
স্টিভেসিভা

0

এটি চেষ্টা করে দেখুন, ইউনিক ফাংশনের সঠিকভাবে কাজ করার জন্য একটি বাছাই করা তালিকা দরকার।

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";

0

অনন্য হ্যাশ কীগুলির ধারণাটি ব্যবহার করে:

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

আউটপুট: acbd

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.