কোটলিনে `ব্রেক` এবং `চালিয়ে যাওয়া E forEach` এ`


119

Kotlin মত, খুব সুন্দর iterating ফাংশন আছে forEachবা repeat, কিন্তু আমি করতে সক্ষম নই breakএবং continueঅপারেটরদের তাদের সঙ্গে কাজ (উভয় স্থানীয় এবং অ-স্থানীয়):

repeat(5) {
    break
}

(1..5).forEach {
    continue@forEach
}

লক্ষ্যটি হ'ল ফাংশনাল সিনট্যাক্সের সাথে যতটা সম্ভব সম্ভবত লুপগুলি অনুকরণ করা। কোটলিনের কিছু পুরানো সংস্করণে এটি অবশ্যই সম্ভব ছিল, তবে বাক্য গঠনটি পুনরুত্পাদন করার জন্য আমি লড়াই করছি।

সমস্যাটি লেবেল (এম 12) সহ একটি বাগ হতে পারে, তবে আমি মনে করি যে প্রথম উদাহরণটি যাইহোক কাজ করা উচিত।

আমার কাছে মনে হয় যে আমি একটি বিশেষ কৌশল / টীকা সম্পর্কে কোথাও পড়েছি তবে আমি এই বিষয়ে কোনও রেফারেন্স পাইনি। নীচের মত চেহারা হতে পারে:

public inline fun repeat(times: Int, @loop body: (Int) -> Unit) {
    for (index in 0..times - 1) {
        body(index)
    }
}

1
বর্তমান কোটলিনে আপনি প্রকৃতপক্ষে এটি নকল করতে পারেন ( বৈশিষ্ট্যগুলি continue@labelএবং break@labelবৈশিষ্ট্যের জন্য অপেক্ষা করার সময় ), সম্পর্কিত প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো
জয়সন মিনার্ড

1
এই প্রশ্নের বিষয়ে আপনাকে শুধুমাত্র existance সম্পর্কে জিজ্ঞাসা করা হবে কিনা তা শোধন ব্যবহার করতে পারে breakএবং continueকার্মিক loops জন্য, অথবা আপনি বিকল্প উত্তরগুলি ঠিক একই জিনিস করে কামনা কর। প্রাক্তনটি কেস হিসাবে উপস্থিত বলে মনে হচ্ছে, কারণ আপনি পরেটিকে প্রত্যাখ্যান করেছেন।
জেসন মিনার্ড

দেখে মনে হচ্ছে তারা কোটলিন ১.৩ এ যোগ করেছেন
টিগ্রান বাবজনায়ান

@ তিগ্রানবাজনায় বাহ! আপনার কি লিংক আছে?
ভোটদান

@ ভোদান, না, আমি এটি চেষ্টা করে
চলেছি

উত্তর:


68

সম্পাদনা :
কোটলিনের ডকুমেন্টেশন অনুসারে , টীকা ব্যবহার করে এটি সম্ভব।

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with explicit label")
}

আসল উত্তর :
যেহেতু আপনি সরবরাহ করেন (Int) -> Unit, আপনি এটি থেকে বিরতি দিতে পারবেন না, যেহেতু সংকলক জানেন না যে এটি একটি লুপে ব্যবহৃত হয়েছিল।

আপনার কাছে কয়েকটি বিকল্প রয়েছে:

লুপের জন্য নিয়মিত ব্যবহার করুন:

for (index in 0 until times) {
    // your code here
}

লুপটি যদি পদ্ধতিটির শেষ কোড হয় তবে
আপনি পদ্ধতিটিreturn থেকে বেরিয়ে আসতে ব্যবহার করতে পারেন (বা return valueযদি এটি unitপদ্ধতি না হয় )।

একটি পদ্ধতি ব্যবহার
করুন একটি কাস্টম পুনরাবৃত্তি পদ্ধতি পদ্ধতি তৈরি করুন যা Booleanচালিয়ে যাওয়ার জন্য ফিরে আসে ।

public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
    for (index in 0 until times) {
        if (!body(index)) break
    }
}

আসলে, আমার প্রশ্নটি নির্দিষ্ট সিনট্যাক্সের কাজটি করা সম্পর্কে ছিল, পুনরাবৃত্তির বিষয়ে নয়। আপনার কি মনে নেই যে কোটলিনের কোনও মাইলফলকটিতে এটি সম্ভব হয়েছিল?
ভদদান

1
মনে নেই। তবে সম্ভবত এটি কারণ আমি বিরতি ব্যবহার করি না এবং অনেকটা চালিয়ে যাই। এই সমস্যাটি দেখুন , এটি "অনুমান - কোনও অনুমান নয়" বলে।
ইওভা স্টার্নবার্গ

1
breakএবং continueশুধুমাত্র লুপগুলিতে কাজ করে। forEach, repeatএবং অন্যান্য সমস্ত পদ্ধতি কেবল এটি: পদ্ধতিগুলি এবং লুপগুলি নয়। Yoav কিছু বিকল্প উপস্থাপন কিন্তু breakcontinueশুধু পদ্ধতি জন্য কাজ ment নেই।
কিরিল রাখমান

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

বর্তমান কোটলিনে আপনি প্রকৃতপক্ষে এটি নকল করতে পারেন ( বৈশিষ্ট্যগুলি continue@labelএবং break@labelবৈশিষ্ট্যের জন্য অপেক্ষা করার সময় ), সম্পর্কিত প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো
জয়সন মিনার্ড

104

এটি 1 থেকে 5 মুদ্রণ করবে Java জাভাতে return@forEachকীওয়ার্ডের মতো কাজ continue, যার অর্থ এই ক্ষেত্রে এটি প্রতিটি লুপটি কার্যকর করে তবে মানটি 5 এর চেয়ে বেশি হলে পরবর্তী পুনরাবৃত্তিতে চলে যায়।

fun main(args: Array<String>) {
    val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    nums.forEach {
       if (it > 5) return@forEach
       println(it)
    }
}

এটি 1 থেকে 10 মুদ্রণ করবে তবে 5 এড়িয়ে যাবে।

fun main(args: Array<String>) {
    val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    nums.forEach {
       if (it == 5) return@forEach
       println(it)
    }
}

কোটলিন খেলার মাঠে তাদের চেষ্টা করুন ।


দুর্দান্ত, তবে কিছু শর্ত পূরণ হওয়ার পরে এটি অসামান্য সময়ের জন্য প্রতিটি শেষ করতে না পারার সমস্যাটির সমাধান করে না। এটি এখনও লুপটি কার্যকর করে চলেছে।
ফক্স

1
@ দ্য ফক্স হ্যাঁ, শর্ত পূরণ করার পরে এটি প্রতিটি লুপ এবং রিটার্ন বাদ দেওয়ার পরে কিছু সম্পাদন করে। ফরইচ এর প্রতিটি অপারেশন একটি ল্যাম্বডা ফাংশন, বর্তমানে ফোরইচ অপারেশনের জন্য কোনও সঠিক ব্রেক ব্রেক নেই। বিরতিটি লুপগুলির জন্য উপলব্ধ, দেখুন: কোটলিংলং.আর্গ
এস-শিকারি

এখানে একটি runnable Kotlin খেলার মাঠ উভয় একটি সঙ্গে snippet এর continueএবং breakউদাহরণ: pl.kotl.in/_LAvET-wX
ashughes

34

একটি বিরতি ব্যবহার করে অর্জন করা যেতে পারে:

//Will produce"12 done with nested loop"
//Using "run" and a tag will prevent the loop from running again. Using return@forEach if I>=3 may look simpler, but it will keep running the loop and checking if i>=3 for values >=3 which is a waste of time.
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}

এবং একটি ধারাবাহিকতা এর সাথে অর্জন করা যেতে পারে:

//Will produce: "1245 done with implicit label"
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
        print(it)
    }
    print(" done with implicit label")
}

এখানে যেহেতু যে কেউ সুপারিশ করেছেন ... ডক্সটি পড়ুন: পি https://kotlinlang.org/docs/references/returns.html#return-at-labels


সুন্দর সমাধান। খুব ভাল কাজ করে। এটি ব্যবহার না করে মনে @loopহয় একইভাবে একই পছন্দসই ফলাফল দেয়।
পারস সিধু

আসলে, আপনি সুস্পষ্ট ট্যাগ "@ লুপ" বাদ দিতে পারেন এবং অন্তর্নিহিত একটি "@ রুন" ব্যবহার করতে পারেন। এখানে মূল দিকটি হ'ল ল্যাম্বডার কলারের কাছে স্থানীয় প্রত্যাবর্তন। নোট করুন যে আপনাকে কিছু স্কোপের ভিতরে লুপটি আবৃত করতে হবে যাতে আপনি পরে এটিকে স্থানীয়ভাবে ফিরিয়ে আনতে পারেন।
রেমন্ড আরতেগা

28

আপনি ল্যাম্বদা এক্সপ্রেশন থেকে রিটার্ন ব্যবহার করতে পারেন যা একটি continueবা নকল করেbreak তার ভিত্তিতে আপনার ব্যবহারের উপর।

এটি সম্পর্কিত প্রশ্নে আচ্ছাদিত: কোটলিনের মধ্যে কার্যকরী লুপের মধ্যে কীভাবে আমি "ব্রেক" বা "চালিয়ে যাও" করব?


17

হিসাবে Kotlin ডকুমেন্টেশন বলেছেন ব্যবহার returnযেতে উপায়। কোটলিন সম্পর্কে ভাল কথা হ'ল যদি আপনার নেস্ট ফাংশন থাকে তবে আপনি যেখান থেকে ফিরে আসবেন তা স্পষ্ট করার জন্য লেবেল ব্যবহার করতে পারেন:

ফাংশন স্কোপ রিটার্ন

fun foo() {
  listOf(1, 2, 3, 4, 5).forEach {
    if (it == 3) return // non-local return directly to the caller of foo()
    print(it)
  }
  println("this point is unreachable")
}

এবং স্থানীয় রিটার্ন (এটি forEach = ধারাবাহিকতা দিয়ে যাওয়া বন্ধ করে না)

fun foo() {
  listOf(1, 2, 3, 4, 5).forEach lit@{
    if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
    print(it)
  }
  print(" done with explicit label")
}

ডকুমেন্টেশন চেকআউট করুন, এটি সত্যিই ভাল :)


3
সতর্কতা: ফিরতি @ forEach
লিটল

ঐটা ঠিক. এটা উদ্দেশ্য। এটি প্রথম সমাধানটি করে তবে আপনার কোনও লুপের ভিতরে নির্দেশাবলী থাকলে আপনি কোথায় / লাফাতে ফিরে যেতে চান তা চয়ন করতে পারেন। দ্বিতীয় ক্ষেত্রে, আমরা যদি কেবল রিটার্ন ব্যবহার করি তবে এটি বন্ধ হবে ;-)
সিজার্ড

কল করা রিটার্ন @ লিট
লাইকগুলি

10

continue আচরণ টাইপ করুন forEach

list.forEach { item -> // here forEach give you data item and you can use it 
    if () {
        // your code
        return@forEach // Same as continue
    }

    // your code
}

জন্য breakটাইপ আচরণ আপনি ব্যবহার করতে হবে for in untilবা for inযেমন প্রতি তালিকা NullableবাNon-Nullable

  1. জন্য Nullable তালিকা:

    for (index in 0 until list.size) {
        val item = list[index] // you can use data item now
        if () {
            // your code
            break
        }
    
        // your code
    }
  2. জন্য অ Nullable তালিকা:

    for (item in list) { // data item will available right away
        if () {
            // your code
            break
        }
    
        // your code
    }

2

প্রতিটি () এর জন্য নেস্টেড লুপগুলির জন্য ব্রেক স্টেটমেন্ট:

listOf("a", "b", "c").forEach find@{ i ->
    listOf("b", "d").forEach { j ->
        if (i == j) return@find
        println("i = $i, j = $j")
    }
}

ফলাফল:

i = a, j = b
i = a, j = d
i = c, j = b
i = c, j = d

বেনামে ফাংশন সহ বিবৃতি চালিয়ে যান:

listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
    if (value == 3) return
    print("$value ")
})

ফলাফল:

1 2 4 5 

0

প্রতিটি জন্য পরিবর্তন হতে পারে

for(it in myList){
   if(condition){
     doSomething()
   }else{
     break //or continue
    }
} 

এটি হ্যাশম্যাপের জন্য কাজ করে

 for(it in myMap){
     val k = it.key
     val v = it.value

       if(condition){
         doSomething()
       }else{
         break //or continue
        }
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.