কিভাবে RecursiveIteratorIterator
কাজ করে?
পিএইচপি ম্যানুয়ালটিতে খুব বেশি দলিলযুক্ত বা ব্যাখ্যা করা যায় না। মধ্যে পার্থক্য কি IteratorIterator
এবং RecursiveIteratorIterator
?
কিভাবে RecursiveIteratorIterator
কাজ করে?
পিএইচপি ম্যানুয়ালটিতে খুব বেশি দলিলযুক্ত বা ব্যাখ্যা করা যায় না। মধ্যে পার্থক্য কি IteratorIterator
এবং RecursiveIteratorIterator
?
RecursiveIteratorIterator
কাজ করে, আপনি কীভাবে IteratorIterator
কাজ করে তা ইতিমধ্যে বুঝতে পেরেছেন ? আমি বলতে চাইছি এটি মূলত একই, কেবলমাত্র দুজনের দ্বারা খাওয়া ইন্টারফেসটি আলাদা। এবং আপনি কয়েকটি উদাহরণে আরও আগ্রহী বা আপনি অন্তর্নিহিত সি কোড প্রয়োগের ভিন্নতা দেখতে চান?
IteratorIterator
মানচিত্র Iterator
এবং IteratorAggregate
একটি মধ্যে Iterator
, যেখানে REcusiveIteratorIterator
ব্যবহার করা হয় recusivly তর্ক করার জন্য একটিRecursiveIterator
উত্তর:
RecursiveIteratorIterator
একটি কংক্রিট হয় Iterator
বাস্তবায়নে গাছ ট্র্যাভেরসাল । এটি একটি প্রোগ্রামারকে এমন একটি ধারক বস্তু যা RecursiveIterator
ইন্টারফেস প্রয়োগ করে , সাধারণ নীতি, প্রকার, শব্দার্থবিজ্ঞান এবং পুনরাবৃত্তকারীগুলির নিদর্শনগুলির জন্য উইকিপিডিয়ায় আইট্রেটরটি দেখতে পায় ables
পার্থক্য ইন IteratorIterator
যা কংক্রিট হয় Iterator
বাস্তবায়নে বস্তুর ট্র্যাভেরসাল রৈখিক অনুক্রমে (এবং ডিফল্টরূপে যে কোন ধরণের গ্রহণ Traversable
তার কন্সট্রাকটর মধ্যে), RecursiveIteratorIterator
একটি ইন সব নোড উপর লুপিং পারবেন আদেশ গাছ অবজেক্টের এবং তার কন্সট্রাকটর একটি লাগে RecursiveIterator
।
সংক্ষেপে: RecursiveIteratorIterator
আপনি একটি গাছের উপর লুপ IteratorIterator
করতে পারবেন, আপনাকে একটি তালিকাতে লুপ করতে দেয়। আমি শীঘ্রই নীচে কিছু কোড উদাহরণ সহ এটি দেখান।
প্রযুক্তিগতভাবে এটি কোনও নোডের সমস্ত বাচ্চাকে (যদি থাকে তবে) ট্র্যাভার করে লিনিয়ারिटी ভেঙে কাজ করে। এটি সম্ভব কারণ সংজ্ঞা অনুসারে নোডের সমস্ত শিশু আবার ক RecursiveIterator
। টপলেভেল Iterator
তার অভ্যন্তরীণভাবে RecursiveIterator
তাদের গভীরতার দ্বারা বিভিন্নগুলি স্ট্যাক করে এবং Iterator
ট্র্যাভারসালের জন্য বর্তমান সক্রিয় সাবটিতে একটি পয়েন্টার রাখে ।
এটি গাছের সমস্ত নোড ঘুরে দেখার অনুমতি দেয়।
অন্তর্নিহিত নীতিগুলি একই সাথে IteratorIterator
: একটি ইন্টারফেস পুনরাবৃত্তির ধরণ নির্দিষ্ট করে এবং বেস পুনরাবৃত্তকারী শ্রেণি এই শব্দার্থবিজ্ঞানের প্রয়োগ। নীচের উদাহরণগুলির সাথে তুলনা করুন, আপনার সাথে লিনিয়ার লুপিংয়ের জন্য foreach
সাধারণত বাস্তবায়নের বিবরণ সম্পর্কে বেশি চিন্তা করবেন না যদি না আপনি কোনও নতুন সংজ্ঞায়িত করার প্রয়োজন হয় Iterator
(যেমন যখন কিছু কংক্রিট টাইপ নিজেই প্রয়োগ করেন না Traversable
)।
রিকার্সিভ ট্র্যাভেরসাল জন্য - যদি না আপনি একটি ব্যবহার করবেন না প্রাক সংজ্ঞায়িত Traversal
ইতিমধ্যে আছে রিকার্সিভ ট্র্যাভেরসাল পুনরাবৃত্তির - আপনি সাধারণত প্রয়োজন বিদ্যমান instantiate করার RecursiveIteratorIterator
পুনরাবৃত্তির বা এমনকি লিখতে একটি recursive ট্র্যাভেরসাল পুনরাবৃত্তির একটি যে Traversable
ট্র্যাভেরসাল পুনরাবৃত্তির সঙ্গে এই ধরনের আছে আপনার নিজের foreach
।
টিপ: আপনি সম্ভবত একটি বা অন্যটিকে নিজের রূপায়িত করেননি, সুতরাং তাদের পার্থক্য সম্পর্কে আপনার ব্যবহারিক অভিজ্ঞতার জন্য এটি করার মতো কিছু হতে পারে। উত্তরের শেষে আপনি একটি ডিআইওয়াই পরামর্শ পান।
সংক্ষেপে প্রযুক্তিগত পার্থক্য:
IteratorIterator
কোনো লাগে Traversable
রৈখিক ট্র্যাভেরসাল জন্য, RecursiveIteratorIterator
আরো একটি নির্দিষ্ট চাহিদা RecursiveIterator
একটি গাছ উপর লুপ।IteratorIterator
এটির Iterator
মাধ্যমে এর প্রধানটিকে উন্মোচিত করে getInnerIerator()
, কেবলমাত্র সেই পদ্ধতির মাধ্যমে RecursiveIteratorIterator
বর্তমান সক্রিয় উপ-সরবরাহ করে Iterator
।IteratorIterator
সম্পূর্ণভাবে নয় পিতা বা মাতা বা শিশু মত কিছু সচেতন, RecursiveIteratorIterator
পেতে এবং ঢুকা শিশুদের কিভাবে পাশাপাশি জানেন।IteratorIterator
পুনরুক্তিকারীদের একটি স্ট্যাকের প্রয়োজন নেই, RecursiveIteratorIterator
এ জাতীয় স্ট্যাক রয়েছে এবং সক্রিয় উপ-পুনরুক্তিকারীকে জানেন।IteratorIterator
রৈখিকতার কারণে এবং তার কোনও পছন্দ না হওয়ার কারণে এর অর্ডার যেখানে রয়েছে, সেখানে RecursiveIteratorIterator
আরও ট্র্যাভারসাল করার জন্য একটি পছন্দ রয়েছে এবং প্রতিটি নোড ( প্রতি মোডেরRecursiveIteratorIterator
মাধ্যমে সিদ্ধান্ত নেওয়া ) অনুযায়ী সিদ্ধান্ত নেওয়া দরকার ।RecursiveIteratorIterator
এর চেয়েও বেশি পদ্ধতি রয়েছে IteratorIterator
।সংক্ষিপ্তসার হিসাবে: RecursiveIterator
একটি কংক্রিট ধরণের পুনরাবৃত্তি (একটি গাছের উপরে লুপিং) যা তার নিজস্ব পুনরাবৃত্তির উপর কাজ করে, যথা RecursiveIterator
। এটি যেমন একই অন্তর্নিহিত নীতি IteratorIerator
, তবে পুনরাবৃত্তির ধরণটি আলাদা (লিনিয়ার ক্রম)।
আদর্শভাবে আপনি নিজের সেটও তৈরি করতে পারেন। শুধুমাত্র প্রয়োজনীয় জিনিস যে আপনার পুনরুক্তিকারীর কার্যকরী Traversable
যা মাধ্যমে সম্ভব Iterator
বা IteratorAggregate
। তারপরে আপনি এটি ব্যবহার করতে পারেন foreach
। উদাহরণস্বরূপ ধারক বস্তুর (গুলি) জন্য নির্দিষ্ট পুনরাবৃত্ত ইন্টারফেসের সাথে এক ধরণের টেরিনারি ট্রি ট্রভারসাল পুনরাবৃত্তি পুনরাবৃত্তি অবজেক্ট।
আসুন এমন কিছু বাস্তব জীবনের উদাহরণ দিয়ে পর্যালোচনা করি যা বিমূর্ত নয়। ইন্টারফেস, কংক্রিট পুনরাবৃত্তকারী, ধারক বস্তু এবং পুনরাবৃত্তি শব্দার্থবিজ্ঞানের মধ্যে এটি সম্ভবত কোনও খারাপ ধারণা নয়।
উদাহরণস্বরূপ একটি ডিরেক্টরি তালিকা নিন। আপনি ডিস্কে নিম্নলিখিত ফাইল এবং ডিরেক্টরি ট্রি পেয়েছেন বিবেচনা করুন:
লিনিয়ার অর্ডার সহ একটি পুনরাবৃত্তি কেবল শীর্ষ স্তরের ফোল্ডার এবং ফাইলগুলি (একটি একক ডিরেক্টরি তালিকা) এর উপর দিয়ে গেলেও পুনরাবৃত্ত পুনরাবৃত্তকারী সাবফোল্ডারগুলির মাধ্যমেও ট্র্যাভ করে এবং সমস্ত ফোল্ডার এবং ফাইল তালিকাভুক্ত করে (যার ডিরেক্টরিগুলি তার উপ-ডিরেক্টরিগুলির তালিকা সহ তালিকাভুক্ত করে):
Non-Recursive Recursive
============= =========
[tree] [tree]
├ dirA ├ dirA
└ fileA │ ├ dirB
│ │ └ fileD
│ ├ fileB
│ └ fileC
└ fileA
আপনি IteratorIterator
এটির সাথে সহজেই তুলনা করতে পারেন যার সাথে ডিরেক্টরিতে ডিরেক্টরি ট্রি অনুসরণ করার জন্য কোনও পুনরাবৃত্তি ঘটে না। এবং RecursiveIteratorIterator
যা গাছটিতে পুনরাবৃত্তির তালিকার শো হিসাবে প্রবেশ করতে পারে।
একটি প্রথম একটি খুব মৌলিক উদাহরণ DirectoryIterator
যে কার্যকরী Traversable
যা করতে পারবেন foreach
করার বারবার এটি উপর:
$path = 'tree';
$dir = new DirectoryIterator($path);
echo "[$path]\n";
foreach ($dir as $file) {
echo " ├ $file\n";
}
উপরের ডিরেক্টরি কাঠামোর জন্য অনুকরণীয় আউটপুট হ'ল:
[tree]
├ .
├ ..
├ dirA
├ fileA
আপনি দেখতে হিসাবে এটি এখনও ব্যবহার করে না IteratorIterator
বা RecursiveIteratorIterator
। পরিবর্তে এটি কেবল ইন্টারফেসে foreach
চালিত ব্যবহার করে Traversable
।
হিসাবে foreach
ডিফল্টভাবে কেবল রৈখিক অর্ডার নামে পুনরাবৃত্তির ধরণ জানে, আমরা স্পষ্টভাবে পুনরাবৃত্তির প্রকার চাইবেন। প্রথম নজরে এটি খুব ভার্জোজ মনে হতে পারে, তবে প্রদর্শনের উদ্দেশ্যে (এবং RecursiveIteratorIterator
পরে আরও দৃশ্যমানের সাথে পার্থক্য তৈরি করার জন্য ), পুনরাবৃত্তির রৈখিক প্রকারটি নির্দিষ্ট IteratorIterator
করে ডিরেক্টরি তালিকাতে পুনরাবৃত্তির ধরণটি স্পষ্টভাবে নির্দিষ্ট করে দিন :
$files = new IteratorIterator($dir);
echo "[$path]\n";
foreach ($files as $file) {
echo " ├ $file\n";
}
এই উদাহরণটি প্রথমটির সাথে প্রায় একই রকম, পার্থক্যটি $files
হ'ল এখন এক IteratorIterator
ধরণের পুনরাবৃত্তি Traversable
$dir
:
$files = new IteratorIterator($dir);
যথারীতি পুনরাবৃত্তির কাজটি সম্পাদন করে foreach
:
foreach ($files as $file) {
আউটপুট ঠিক একই। তাহলে আলাদা কি? এর মধ্যে ব্যবহৃত বস্তুটি ভিন্ন foreach
। প্রথম উদাহরণে এটি একটি হল DirectoryIterator
দ্বিতীয় উদাহরণে এটা IteratorIterator
। এটি দেখায় নমনীয়তা পুনরাবৃত্তিকারীদের: আপনি একে অপরের সাথে প্রতিস্থাপন করতে পারেন, অভ্যন্তরীণ কোডটি foreach
কেবল প্রত্যাশা অনুযায়ী কাজ চালিয়ে যেতে পারে।
সাব ডিরেক্টরিগুলি সহ পুরো তালিকা পেতে শুরু করুন।
যেহেতু আমরা এখন পুনরাবৃত্তির ধরণ উল্লেখ করেছি, আসুন এটি অন্য ধরণের পুনরাবৃত্তিতে পরিবর্তন করতে বিবেচনা করুন।
আমরা জানি আমাদের প্রথম গাছটি কেবল প্রথম স্তরের নয়, এখনই পুরো গাছটি অতিক্রম করতে হবে। একটি সহজ সঙ্গে যে কাজ আছে করার foreach
আমরা পুনরুক্তিকারীর নিয়ে বিভিন্ন ধরনের প্রয়োজন: RecursiveIteratorIterator
। এবং যেটি কেবলমাত্র সেই কনটেইনার বস্তুগুলির মধ্যে পুনরাবৃত্তি করতে পারে যার RecursiveIterator
ইন্টারফেস রয়েছে ।
ইন্টারফেসটি একটি চুক্তি। এটি প্রয়োগকারী যে কোনও শ্রেণীর সাথে একসাথে ব্যবহার করা যেতে পারে RecursiveIteratorIterator
। এই জাতীয় শ্রেণীর উদাহরণ হ'ল RecursiveDirectoryIterator
, যা এর পুনরাবৃত্ত রূপের মতো DirectoryIterator
।
আই-শব্দের সাথে অন্য কোনও বাক্য লেখার আগে একটি প্রথম কোড উদাহরণ দেখতে দিন:
$dir = new RecursiveDirectoryIterator($path);
echo "[$path]\n";
foreach ($dir as $file) {
echo " ├ $file\n";
}
এই তৃতীয় উদাহরণটি প্রথমটির সাথে প্রায় একই রকম, তবে এটি কিছু আলাদা আউটপুট তৈরি করে:
[tree]
├ tree\.
├ tree\..
├ tree\dirA
├ tree\fileA
ঠিক আছে, এর চেয়ে আলাদা নয়, ফাইলের নামটিতে এখন সামনের পথের নামটি রয়েছে, তবে বাকিগুলিও একইরকম দেখাচ্ছে।
যেমন উদাহরণটি দেখায়, এমনকি ডিরেক্টরি অবজেক্টটি ইতিমধ্যে RecursiveIterator
ইন্টারফেসকে পরিপূরণ করে , foreach
এটি পুরো ডিরেক্টরি ট্রিটিকে অতিক্রম করতে যথেষ্ট নয় । এখানেই কার্যকর হয় RecursiveIteratorIterator
। উদাহরণ 4 দেখায় কিভাবে:
$files = new RecursiveIteratorIterator($dir);
echo "[$path]\n";
foreach ($files as $file) {
echo " ├ $file\n";
}
RecursiveIteratorIterator
কেবল পূর্ববর্তী $dir
অবজেক্টের পরিবর্তে ব্যবহার foreach
করা সমস্ত ফাইল এবং ডিরেক্টরিকে পুনরাবৃত্ত পদ্ধতিতে অতিক্রম করবে । এটি তখন সমস্ত ফাইল তালিকাভুক্ত করে, কারণ বস্তুর পুনরাবৃত্তির ধরণটি এখন নির্দিষ্ট করা হয়েছে:
[tree]
├ tree\.
├ tree\..
├ tree\dirA\.
├ tree\dirA\..
├ tree\dirA\dirB\.
├ tree\dirA\dirB\..
├ tree\dirA\dirB\fileD
├ tree\dirA\fileB
├ tree\dirA\fileC
├ tree\fileA
এটি ইতিমধ্যে ফ্ল্যাট এবং গাছের ট্র্যাভারসাল মধ্যে পার্থক্য প্রদর্শন করা উচিত। RecursiveIteratorIterator
উপাদানের একটি তালিকা যে কোন গাছ মত গঠন, তর্ক করতে সক্ষম হয়। যেহেতু এখানে আরও তথ্য রয়েছে (যেমন স্তরটি পুনরাবৃত্তিটি বর্তমানে সঞ্চালিত হয় তার মতো), এটির উপরে পুনরাবৃত্তি করার সময় পুনরাবৃত্ত বস্তুটি অ্যাক্সেস করা সম্ভব এবং উদাহরণস্বরূপ আউটপুট ইনডেন্ট করা:
echo "[$path]\n";
foreach ($files as $file) {
$indent = str_repeat(' ', $files->getDepth());
echo $indent, " ├ $file\n";
}
এবং উদাহরণ 5 এর আউটপুট :
[tree]
├ tree\.
├ tree\..
├ tree\dirA\.
├ tree\dirA\..
├ tree\dirA\dirB\.
├ tree\dirA\dirB\..
├ tree\dirA\dirB\fileD
├ tree\dirA\fileB
├ tree\dirA\fileC
├ tree\fileA
অবশ্যই এটি কোনও সৌন্দর্য প্রতিযোগিতা জিততে পারে না, তবে এটি দেখায় যে পুনরাবৃত্তির পুনরাবৃত্তকারীটির সাথে কী এবং মানটির লিনিয়ার ক্রম ছাড়া আরও তথ্য পাওয়া যায় । এমনকি foreach
কেবল এই ধরণের রৈখিকতা প্রকাশ করতে পারে, পুনরাবৃত্তকারীকে অ্যাক্সেস করা নিজেই আরও তথ্য পেতে পারে।
মেটা-তথ্যের অনুরূপ, গাছকে কীভাবে অতিক্রম করতে হবে এবং এর ফলে আউটপুট অর্ডার করার বিভিন্ন উপায়ও রয়েছে। এই মোড এরRecursiveIteratorIterator
এবং এটি কন্সট্রাকটর সঙ্গে নির্ধারণ করা যাবে।
পরবর্তী উদাহরণটি RecursiveDirectoryIterator
ডট এন্ট্রিগুলি ( .
এবং ..
) অপসারণ করতে বলবে কারণ আমাদের প্রয়োজন নেই them তবে পুনরাবৃত্তি মোডটি SELF_FIRST
বাচ্চাদের আগে (সাব-ডিরেক্টরীতে ফাইল এবং সাব-সাবডিয়ার্স ) প্রথমে প্যারেন্ট এলিমেন্টকে (সাব-ডাইরেক্টরি) নিতে নেওয়া হবে :
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::SELF_FIRST);
echo "[$path]\n";
foreach ($files as $file) {
$indent = str_repeat(' ', $files->getDepth());
echo $indent, " ├ $file\n";
}
আউটপুট এখন সাবডিরেক্টরি এন্ট্রিগুলি সঠিকভাবে তালিকাভুক্ত দেখায়, আপনি যদি পূর্ববর্তী আউটপুটটি সেখানে উপস্থিত না থেকে তুলনা করেন:
[tree]
├ tree\dirA
├ tree\dirA\dirB
├ tree\dirA\dirB\fileD
├ tree\dirA\fileB
├ tree\dirA\fileC
├ tree\fileA
পুনরাবৃত্তি মোড তাই এবং কখন গাছের একটি ব্রাচ বা পাতা ফিরে আসে তা নিয়ন্ত্রণ করে, উদাহরণস্বরূপ ডিরেক্টরি উদাহরণের জন্য:
LEAVES_ONLY
(ডিফল্ট): কেবল ফাইলগুলি তালিকাবদ্ধ করুন, কোনও ডিরেক্টরি নেই।SELF_FIRST
(উপরে): তালিকা ডিরেক্টরি এবং তারপরে সেখানে ফাইলগুলি।CHILD_FIRST
(ডাব্লু / ও উদাহরণ): প্রথমে সাব-ডিরেক্টরিতে ফাইল তালিকাভুক্ত করুন, তারপরে ডিরেক্টরিটি।অন্য দুটি মোডের সাথে উদাহরণ 5 এর আউটপুট :
LEAVES_ONLY CHILD_FIRST
[tree] [tree]
├ tree\dirA\dirB\fileD ├ tree\dirA\dirB\fileD
├ tree\dirA\fileB ├ tree\dirA\dirB
├ tree\dirA\fileC ├ tree\dirA\fileB
├ tree\fileA ├ tree\dirA\fileC
├ tree\dirA
├ tree\fileA
আপনি যখন এটি স্ট্যান্ডার্ড ট্র্যাভারসাল সাথে তুলনা করেন, এই সমস্ত জিনিস উপলব্ধ হয় না। পুনরাবৃত্তির পুনরাবৃত্তির ফলে আপনার মাথাটি যখন আপনার চারপাশে মুড়ে ফেলার দরকার হয় তখন এটি আরও জটিল হয় তবে এটি ব্যবহার করা সহজ কারণ এটি কেবল একটি পুনরুক্তির মতো আচরণ করে, আপনি এটি একটিতে রেখে দিয়ে গিয়েছেন foreach
।
আমি মনে করি এগুলি একটি উত্তরের জন্য যথেষ্ট উদাহরণ। আপনি পুরো উত্স-কোডের পাশাপাশি এই গিস্টটিতে সুন্দর চেহারার অ্যাস্কি-গাছগুলি প্রদর্শন করার জন্য একটি উদাহরণ পেতে পারেন: https://gist.github.com/3599532
এটি নিজেই করুন:
RecursiveTreeIterator
লাইন দিয়ে কাজের লাইন তৈরি করুন ।
5 উদাহরণ উদাহরণস্বরূপ প্রমাণ করেছে যে পুনরাবৃত্তকারীদের রাষ্ট্রের সম্পর্কে মেটা-তথ্য রয়েছে। যাইহোক, এই উদ্দেশ্যপূর্ণ প্রদর্শিত হয়েছে মধ্যেforeach
পুনরাবৃত্তির। বাস্তব জীবনের এই স্বাভাবিকভাবেই ভিতরে জন্যে RecursiveIterator
।
এর চেয়ে ভাল উদাহরণ হ'ল RecursiveTreeIterator
, এটি ইনডেন্টিং, প্রিফিক্সিং ইত্যাদির যত্ন নেয়। নিম্নলিখিত কোড টুকরা দেখুন:
$dir = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS);
$lines = new RecursiveTreeIterator($dir);
$unicodeTreePrefix($lines);
echo "[$path]\n", implode("\n", iterator_to_array($lines));
RecursiveTreeIterator
লাইন দ্বারা কাজ লাইন দেয়ার উদ্দেশ্যে করা হচ্ছে, আউটপুট চমত্কার সোজা এক সামান্য সমস্যা নিয়ে এগিয়ে হল:
[tree]
├ tree\dirA
│ ├ tree\dirA\dirB
│ │ └ tree\dirA\dirB\fileD
│ ├ tree\dirA\fileB
│ └ tree\dirA\fileC
└ tree\fileA
RecursiveDirectoryIterator
এটির সাথে সংমিশ্রণে ব্যবহার করার সময় এটি কেবলমাত্র ফাইলের নামটিই নয় পুরো পথটি প্রদর্শন করে। বাকিটা দেখতে ভাল লাগছে। কারণ ফাইল-নামগুলি উত্পন্ন হয় SplFileInfo
। সেগুলি পরিবর্তে বেসনাম হিসাবে প্রদর্শিত হবে। পছন্দসই আউটপুট নিম্নলিখিত:
/// Solved ///
[tree]
├ dirA
│ ├ dirB
│ │ └ fileD
│ ├ fileB
│ └ fileC
└ fileA
একটি ডেকোরেটার ক্লাস তৈরি করুন যা এর RecursiveTreeIterator
পরিবর্তে ব্যবহার করা যেতে পারে RecursiveDirectoryIterator
। এটি পথের SplFileInfo
পরিবর্তে বর্তমানের বেসনামটি সরবরাহ করতে হবে। চূড়ান্ত কোড খণ্ডটি এর পরে দেখতে পেল:
$lines = new RecursiveTreeIterator(
new DiyRecursiveDecorator($dir)
);
$unicodeTreePrefix($lines);
echo "[$path]\n", implode("\n", iterator_to_array($lines));
এই টুকরোগুলি সহ পরিশিষ্টের$unicodeTreePrefix
সংক্ষেপের অংশ : এটি নিজে করুন: RecursiveTreeIterator
লাইনের সাহায্যে ওয়ার্ক লাইন করুন । ।
RecursiveIteratorIterator
এড়িয়ে গেছি কারণ এটি অন্যান্য ধরণের সাথে সাধারণ তবে এটি কীভাবে কাজ করে তা সম্পর্কে আমি কিছু প্রযুক্তিগত ইনফোস দিয়েছিলাম। আমি যে উদাহরণগুলি মনে করি তা পার্থক্যগুলি ভালভাবে দেখায়: পুনরাবৃত্তির ধরণ হ'ল উভয়ের মধ্যে প্রধান পার্থক্য। আপনি যদি পুনরাবৃত্তির ধরণটি কিছুটা আলাদাভাবে মুদ্রা করেন তবে কোনও ধারণা নেই তবে শব্দার্থবিজ্ঞানের ধরণের পুনরাবৃত্তির সাথে আইএমএইচও সহজ নয়।
এর পার্থক্য কী
IteratorIterator
এবংRecursiveIteratorIterator
?
এই দুটি পুনরাবৃত্তির মধ্যে পার্থক্য বুঝতে, প্রথমে ব্যবহৃত নামকরণ কনভেনশনগুলি এবং "পুনরাবৃত্ত" পুনরাবৃত্তকারী বলতে আমরা কী বোঝাতে চাইছি তার সম্পর্কে প্রথমে কিছুটা বুঝতে হবে।
পিএইচপি-তে অ-পুনরুক্তিযুক্ত পুনরুক্তি রয়েছে, যেমন ArrayIterator
এবংFilesystemIterator
। এছাড়াও "পুনরাবৃত্ত" পুনরুক্তি রয়েছে যেমন RecursiveArrayIterator
এবং RecursiveDirectoryIterator
। পরেরগুলিতে এমন পদ্ধতি রয়েছে যেগুলি এগুলিকে ড্রিল করতে সক্ষম করে, আগেরটি তা করে না।
এই পুনরাবৃত্তকারীগুলির উদাহরণগুলি যখন তাদের নিজস্বভাবে লুপ করা হয়, এমনকি পুনরাবৃত্তকারীগুলিও, মানগুলি কেবল "শীর্ষ" স্তর থেকে আসে এমনকি সাব-ডিরেক্টরি সহ নেস্টেড অ্যারে বা ডিরেক্টরিতে লুপ করা হলেও।
পুনরাবৃত্তির পুনরাবৃত্তকারীরা পুনরাবৃত্ত আচরণ (মাধ্যমে , ) প্রয়োগ করে তবে শোষণ করে নাhasChildren()
getChildren()
এটি না।
পুনরাবৃত্তির পুনরাবৃত্তকারীদের "পুনরাবৃত্তিযোগ্য" পুনরাবৃত্তকারী হিসাবে ভাবা ভাল, তাদের ক্ষমতা আছে পুনরাবৃত্তভাবে পুনরাবৃত্তি তবে কেবল এই শ্রেণীর একটির উদাহরণ দিয়ে পুনরাবৃত্তি করবে না। পুনরাবৃত্তিমূলক আচরণ কাজে লাগাতে, পড়া চালিয়ে যান।
এখানেই RecursiveIteratorIterator
খেলতে আসে। এটি "পুনরাবৃত্তযোগ্য" পুনরাবৃত্তিকে এমনভাবে কল করতে পারে যাতে কোনও কাঠামোর মধ্যে কোনও সাধারণ, ফ্ল্যাট, লুপে ড্রিল করতে হয়। এটি পুনরাবৃত্ত আচরণকে ক্রিয়ায় ফেলেছে। এটি মূলত পুনরাবৃত্তির প্রতিটি মানগুলিতে পদক্ষেপ নেওয়ার কাজটি দেখায়, "বাচ্চাদের" পুনরাবৃত্তি করার জন্য "বাচ্চারা" আছে কিনা তা দেখার চেষ্টা করে এবং সেই সমস্ত বাচ্চাদের সংগ্রহের মধ্যে এবং বাইরে বেরিয়ে আসার কাজটি করে। আপনি কোনও ভবিষ্যতের নজির আটকে RecursiveIteratorIterator
রেখেছেন এবং এটি কাঠামোর মধ্যে ডুব দেয় যাতে আপনার দরকার নেই।
যদি RecursiveIteratorIterator
ব্যবহার করা হয়নি, আপনি রিকার্সিভ আচরণ কাজে লাগান আপনার নিজস্ব রিকার্সিভ লুপ লিখতে হবে "recursible" পুনরুক্তিকারীর এর বিরুদ্ধে চেক hasChildren()
এবং ব্যবহার getChildren()
।
সুতরাং এটির একটি সংক্ষিপ্ত বিবরণ RecursiveIteratorIterator
, এটি কীভাবে আলাদা IteratorIterator
? ঠিক আছে, আপনি মূলত একই ধরণের প্রশ্ন জিজ্ঞাসা করছেন বিড়ালছানা এবং গাছের মধ্যে পার্থক্য কী? উভয়ই একই এনসাইক্লোপিডিয়াতে উপস্থিত হওয়ার কারণে (বা পুনরুক্তিকারীদের জন্য ম্যানুয়াল) এর অর্থ এই নয় যে আপনার দুজনের মধ্যে বিভ্রান্ত হওয়া উচিত।
এর কাজটি IteratorIterator
হ'ল যে কোনও Traversable
বস্তু গ্রহণ করা এবং এটি এমনভাবে মোড়ানো হয় যা এটি Iterator
ইন্টারফেসটিকে সন্তুষ্ট করে । এর জন্য একটি ব্যবহার তারপরে অ-পুনরাবৃত্তকারী অবজেক্টে পুনরাবৃত্ত-নির্দিষ্ট আচরণ প্রয়োগ করতে সক্ষম হবেন।
ব্যবহারিক উদাহরণ দেওয়ার জন্য, DatePeriod
ক্লাসটি Traversable
কিন্তু একটি নয় Iterator
। এর মতো, আমরা এর মানগুলি লুপ foreach()
করতে পারি তবে সাধারণভাবে কোনও পুনরুক্তিকারীর সাথে ফিল্টারিংয়ের মতো অন্যান্য জিনিসগুলি আমরা করতে পারি না।
টাস্ক : আগামী চার সপ্তাহের সোমবার, বুধবার ও শুক্রবারে লুপ।
হ্যাঁ, এই দ্বারা তুচ্ছ হয় foreach
ওভার -ing DatePeriod
এবং ব্যবহার if()
লুপ মধ্যে; কিন্তু এটি এই উদাহরণের বিন্দু নয়!
$period = new DatePeriod(new DateTime, new DateInterval('P1D'), 28);
$dates = new CallbackFilterIterator($period, function ($date) {
return in_array($date->format('l'), array('Monday', 'Wednesday', 'Friday'));
});
foreach ($dates as $date) { … }
উপরের স্নিপেটটি কাজ করবে না কারণ ইন্টারফেসটি CallbackFilterIterator
কার্যকর করে এমন কোনও শ্রেণীর উদাহরণের প্রত্যাশা করে Iterator
, যা DatePeriod
না। তবে এটি যেহেতু Traversable
আমরা সহজেই ব্যবহার করে সেই প্রয়োজনীয়তাটি পূরণ করতে পারি IteratorIterator
।
$period = new IteratorIterator(new DatePeriod(…));
যেমন আপনি দেখতে পাচ্ছেন, এটির পুনরাবৃত্তিকারী ক্লাস বা পুনরাবৃত্তিগুলির সাথে পুনরাবৃত্তি করার কিছুই করার নেই এবং এর মধ্যে IteratorIterator
এবং এর মধ্যে পার্থক্য রয়েছে RecursiveIteratorIterator
।
RecursiveIteraratorIterator
একটি RecursiveIterator
("পুনরাবৃত্তযোগ্য" পুনরুক্তিযোগ্য) এর মাধ্যমে পুনরাবৃত্তি করার জন্য, উপলব্ধ যে পুনরাবৃত্তির আচরণ ব্যবহার করে।
IteratorIterator
Iterator
অ-পুনরুক্তকারী, Traversable
বস্তুগুলিতে আচরণ প্রয়োগের জন্য ।
IteratorIterator
ঠিক রৈখিক অর্ডার ট্র্যাভেরসাল মান টাইপ Traversable
বস্তু? যা এগুলি ছাড়া এটি ব্যবহার করা যেতে পারে ঠিক foreach
তেমন? আর এমনকি আরও, না একটি হয় RecursiveIterator
সবসময় একটি Traversable
এবং সেইজন্য না শুধুমাত্র IteratorIterator
কিন্তু RecursiveIteratorIterator
সবসময় "আবেদন করার জন্য Iterator
অ পুনরুক্তিকারীর, Traversable বস্তু ব্যবহার" ? (আমি এখন বলতে চাই foreach
যে ধারক বস্তুর মাধ্যমে পুনরাবৃত্তির বস্তুর মাধ্যমে পুনরাবৃত্তির ধরণের প্রয়োগ করা হয় যা কোনও পুনরাবৃত্ত-ধরণের ইন্টারফেস প্রয়োগ করে তাই এগুলি সর্বদা Traversable
IteratorIterator
এটি এমন একটি শ্রেণি যা সমস্ত কিছুগুলিতে মোড়কে Traversable
রাখা Iterator
। এর চেয়ে বেশি কিছু নেই । আপনি এই শব্দটি আরও সাধারণভাবে প্রয়োগ করছেন বলে মনে হচ্ছে।
Recursive
মধ্যে RecursiveIterator
, ব্যবহার বোঝা যেহেতু আরও উপযুক্ত নাম এক যা সামর্থ্য বর্ণনা করে, মত হত RecursibleIterator
।
এর সাথে ব্যবহার করা হলে iterator_to_array()
, RecursiveIteratorIterator
সমস্ত মান সন্ধান করতে পুনরাবৃত্তভাবে অ্যারে চলবে। এর অর্থ এটি আসল অ্যারে সমতল করবে।
IteratorIterator
মূল শ্রেণিবদ্ধ কাঠামো রাখবে।
এই উদাহরণটি আপনাকে পরিষ্কারভাবে পার্থক্য দেখাবে:
$array = array(
'ford',
'model' => 'F150',
'color' => 'blue',
'options' => array('radio' => 'satellite')
);
$recursiveIterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
var_dump(iterator_to_array($recursiveIterator, true));
$iterator = new IteratorIterator(new ArrayIterator($array));
var_dump(iterator_to_array($iterator,true));
new IteratorIterator(new ArrayIterator($array))
এর সমতুল্য new ArrayIterator($array)
, বাহ্যিক IteratorIterator
কিছুই করছে না। তদুপরি, আউটপুট সমতলকরণের কোনও সম্পর্ক নেই iterator_to_array
- এটি কেবল পুনরাবৃত্তিকে অ্যারেতে রূপান্তর করে। সমতলকরণ RecursiveArrayIterator
তার অভ্যন্তর পুনরাবৃত্তির পথে চলার একটি বৈশিষ্ট্য ।
পুনরাবৃত্তির ডিরেক্টরি নির্দেশক এটি পুরো ফাইলের নামটি প্রদর্শন করে কেবল ফাইলের নামই না। বাকিটা দেখতে ভাল লাগছে। কারণ ফাইল-নামগুলি স্প্লফিলআইএনফো দ্বারা উত্পাদিত হয়েছিল। সেগুলি পরিবর্তে বেসনাম হিসাবে প্রদর্শিত হবে। পছন্দসই আউটপুট নিম্নলিখিত:
$path =__DIR__;
$dir = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($dir,RecursiveIteratorIterator::SELF_FIRST);
while ($files->valid()) {
$file = $files->current();
$filename = $file->getFilename();
$deep = $files->getDepth();
$indent = str_repeat('│ ', $deep);
$files->next();
$valid = $files->valid();
if ($valid and ($files->getDepth() - 1 == $deep or $files->getDepth() == $deep)) {
echo $indent, "├ $filename\n";
} else {
echo $indent, "└ $filename\n";
}
}
আউটপুট:
tree
├ dirA
│ ├ dirB
│ │ └ fileD
│ ├ fileB
│ └ fileC
└ fileA