ফরচ-অবজেক্টে 'ব্রেক' করার মতো আচরণ কেন চালিয়ে যায়?


123

যদি আমি পাওয়ারশেল স্ক্রিপ্টে নিম্নলিখিতগুলি করি:

$range = 1..100
ForEach ($_ in $range) {
    if ($_ % 7 -ne 0 ) { continue; }
    Write-Host "$($_) is a multiple of 7"
}

আমি এর প্রত্যাশিত আউটপুট পাই:

7 is a multiple of 7
14 is a multiple of 7
21 is a multiple of 7
28 is a multiple of 7
35 is a multiple of 7
42 is a multiple of 7
49 is a multiple of 7
56 is a multiple of 7
63 is a multiple of 7
70 is a multiple of 7
77 is a multiple of 7
84 is a multiple of 7
91 is a multiple of 7
98 is a multiple of 7

যাইহোক, যদি আমি একটি পাইপলাইন ব্যবহার এবং ForEach-Object, continueপাইপলাইন লুপ আউট বিরতি বলে মনে হয়।

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) { continue; }
    Write-Host "$($_) is a multiple of 7"
}

continueএখনও ফোরএচ-অবজেক্ট করার সময় আমি কী সদৃশ আচরণ পেতে পারি , তাই আমার পাইপলাইনটি ব্রেকআপ করতে হবে না?


এখানে ব্যবহার করার জন্য প্রচুর কমান্ড সহ একটি পৃষ্ঠা রয়েছে foreach: techotopia.com/index.php/…
বিজিএম কোডার

উত্তর:


164

কেবলমাত্র এর returnপরিবর্তে ব্যবহার করুন continue। এটি returnস্ক্রিপ্ট ব্লক থেকে প্রত্যাবর্তন করে যা ForEach-Objectএকটি নির্দিষ্ট পুনরাবৃত্তির মাধ্যমে আহ্বান করা হয়, সুতরাং এটি continueএকটি লুপে অনুকরণ করে ।

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) { return }
    Write-Host "$($_) is a multiple of 7"
}

রিফ্যাক্টর করার সময় মনে রাখা দরকার got কখনও কখনও কেউ একটি foreachস্টেটমেন্ট ব্লককে একটি ForEach-Objectসেমিডলেট দিয়ে পাইপলাইনে রূপান্তর করতে চায় (এটির এমন একটি উপাধিও রয়েছে যা foreachএই রূপান্তরটিকে সহজতর করতে এবং ভুলগুলিও সহজতর করতে সহায়তা করে)। সমস্ত continueগুলি সঙ্গে প্রতিস্থাপন করা উচিতreturn

দ্রষ্টব্য: দুর্ভাগ্যবশত, এটা যে সহজ অনুকরণ নয় breakমধ্যে ForEach-Object


2
কি ওপি বলছে দৃশ্যত থেকে continueএকটি অনুকরণ ব্যবহার করা যেতে পারে breakForEach-Object:)
রিচার্ড Hauer

6
@ রিচার্ড হাউর এমন স্ক্রিনটি continueকেবল ForEach-Objectযেখানে ব্যবহৃত হয়েছে তা নয়, পুরো স্ক্রিপ্টটি ভেঙে ফেলবে ।
রোমান কুজমিন

22

কারণ For-Eachবস্তুর একটি cmdlet এবং একটি লুপ এবং continueএবং breakএটি প্রযোজ্য হবে না।

উদাহরণস্বরূপ, যদি আপনার:

$b = 1,2,3

foreach($a in $b) {

    $a | foreach { if ($_ -eq 2) {continue;} else {Write-Host $_} }

    Write-Host  "after"
}

আপনি আউটপুট হিসাবে পাবেন:

1
after
3
after

এটি কারণ continueবাইরের ফোরচ লুপে প্রয়োগ করা হয় এবং ফোরচ-অবজেক্ট সেমিডলেট নয়। কোনও লুপের অভাবে, বহিরাগত স্তর, অতএব আপনাকে এটির মতো অভিনয় করার একটি ধারণা দেয় break

তাহলে আপনি কীভাবে continueসদৃশ আচরণ পাবেন? এক উপায় হ'ল হু-অবজেক্ট অফ কোর্স:

1..100 | ?{ $_ % 7  -eq 0} | %{Write-Host $_ is a multiple of 7}

যেখানে-অবজেক্ট সেমিডলেট ব্যবহার করা ভাল পরামর্শ। আমার আসল ক্ষেত্রে, আমি মনে করি না যে কোডটি পড়ার পক্ষে একক লম্বা লাইনে স্টেট স্টেটমেন্টের আগে কোডের একাধিক লাইন তৈরি করা বুদ্ধিমান হয়ে আসে। তবে, এটি অন্যান্য পরিস্থিতিতে আমার জন্য কাজ করবে।
জাস্টিন ডিয়ারিং

@ জাস্টিনডিয়ারিং - In my actual case, I don't think it makes sense to make the multiple lines of code preceding my if statement into a single long line of hard to read code.আপনার অর্থ কী?
manojlds

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

আমার ক্ষেত্রে এটি সঠিক উত্তর ছিল, আমি যে অবজেক্টগুলি চালিয়ে যাচ্ছি তা ফিল্টার করার জন্য একটি শর্ত যুক্ত করুন বা আবার ফিরে আসুন যাতে আমার সেগুলি প্রথম স্থানে প্রক্রিয়াকরণের দরকার না হয়। +1
ক্রিস ম্যাগনসন

3

অন্য বিকল্প হ্যাক ধরনের, কিন্তু আপনি একবার চালানো হবে যে একটি লুপ আপনার ব্লক মোড়ানো করতে পারেন। এইভাবে, continueপছন্দসই প্রভাব ফেলবে:

1..100 | ForEach-Object {
    for ($cont=$true; $cont; $cont=$false) {
        if ($_ % 7 -ne 0 ) { continue; }
        Write-Host "$($_) is a multiple of 7"
    }
}

4
সত্যি বলতে কী, এটি কুৎসিত :) এবং কেবল একটি হ্যাক নয় কারণ ফোরচ-অবজেক্টের পরিবর্তে আপনি একটি ফোরচ লুপ ব্যবহার করতে পারেন।
manojlds

1
@ মানোজাল্ডস: ১.১০০ শুধুমাত্র চিত্রের জন্য। ($ মিথ্যা) ঠিক যেমন কাজ করে ঠিক তেমনি লুপ এবং আরও কিছুটা স্বজ্ঞাত হিসাবে কাজ করে।
হ্যারি মার্টেরোসিয়ান

2

একটি সাধারণ elseবিবৃতি এটিকে যেমন কাজ করে তোলে:

1..100 | ForEach-Object {
    if ($_ % 7 -ne 0 ) {
        # Do nothing
    } else {
        Write-Host "$($_) is a multiple of 7"
    }
}

বা একটি পাইপলাইনে:

1..100 | ForEach-Object { if ($_ % 7 -ne 0 ) {} else {Write-Host "$($_) is a multiple of 7"}}

তবে আরও কার্যকর সমাধান হ'ল আপনার পরীক্ষাটি উল্টানো এবং কেবলমাত্র আপনার সাফল্যের জন্য আউটপুট উত্পন্ন করা

1..100 | ForEach-Object {if ($_ % 7 -eq 0 ) {Write-Host "$($_) is a multiple of 7"}}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.