দ্রুতগতিতে বিপরীতে ক্রমে লুপের জন্য পুনরাবৃত্তি কিভাবে করবেন?


186

যখন আমি প্লেগ্রাউন্ডে লুপের জন্য ব্যবহার করি, তখন লুপের সর্বোচ্চ পরামিতিটি সর্বোচ্চ মান না হওয়া পর্যন্ত সবকিছু ঠিকঠাক কাজ করে। (অবতরণ ক্রমে পুনরাবৃত্তি)

এটি কি বাগ? অন্য কারও কাছে আছে?

for index in 510..509
{
    var a = 10
}

মৃত্যুদন্ড কার্যকর করা হবে এমন পুনরাবৃত্তির সংখ্যা প্রদর্শন করে এমন কাউন্টারটি টিক টিকিয়ে রাখে ...

এখানে চিত্র বর্ণনা লিখুন



1
সি স্টাইল লুপগুলি ড্রপ করার মতো উজ্জ্বল সিদ্ধান্ত। তাদের ফিরিয়ে আনুন
জোয়েল টেপ্লি

আমার উত্তরটি সুইফট 5 এর সাথে দেখুন যা বিপরীত ক্রমে পুনরাবৃত্তি করার 4 টি বিভিন্ন উপায় দেখায়।
Imanou পেটিট

উত্তর:


229

এক্সকোড 6 বিটা 4 একটি ব্যতীত অন্য একটি পদক্ষেপ সহ রেঞ্জগুলিতে পুনরাবৃত্তি করতে দুটি ফাংশন যুক্ত করেছে: stride(from: to: by:)যা একচেটিয়া রেঞ্জগুলির সাথে ব্যবহৃত হয় এবং stride(from: through: by:)যা অন্তর্ভুক্ত ব্যাপ্তির সাথে ব্যবহৃত হয়।

বিপরীত ক্রমে একটি ব্যাপ্তিতে পুনরাবৃত্তি করতে, সেগুলি নীচের হিসাবে ব্যবহার করা যেতে পারে:

for index in stride(from: 5, to: 1, by: -1) {
    print(index)
}
//prints 5, 4, 3, 2

for index in stride(from: 5, through: 1, by: -1) {
    print(index)
}
//prints 5, 4, 3, 2, 1

মনে রাখবেন যে এগুলির কোনওটিই Rangeসদস্য কার্য নয়। এগুলি বিশ্বব্যাপী ফাংশন যা একটি StrideToবা StrideThroughস্ট্রাক্টকে দেয়, যা কাঠামোর চেয়ে পৃথকভাবে সংজ্ঞায়িত করা হয় Range

এই উত্তরের পূর্ববর্তী সংস্করণটি স্ট্রাক্টের by()সদস্য ফাংশনটি ব্যবহার করেছে Range, যা বিটা ৪-এ সরানো হয়েছে, আপনি কীভাবে এটি দেখতে চান তা সম্পাদনা ইতিহাস পরীক্ষা করে দেখুন check


26
সুইফট ২.০ সহ এটি এখন: 5.stride(to: 1, by: -1)বা5.stride(through: 1, by: -1)
বাইনারিয়ার

6
সুইফট ৩.০ সহ আমরা ফ্রি ফাংশন হিসাবে ফিরে এসেছি।
সেজার

@ শান এটি একটি যুক্তিসঙ্গত এবং নিরাপদ পছন্দ। আমি আপনাকে বলতে পারি না প্রায়শই আর প্রোগ্রামাররা এর :অপারেটর দ্বারা সুস্পষ্টভাবে নীচের দিকে পুনরাবৃত্তি করে, যার ফলে তাদের লুপগুলি এড়িয়ে যায় thought এটি ইন্টারেক্টিভ ব্যবহারের জন্য খুব সুবিধাজনক, তবে স্ক্রিপ্টগুলিতে ভয়াবহ ত্রুটিযুক্ত এমন বিন্দুতে যেখানে স্টাইল গাইডরা এটি ব্যবহারের বিরুদ্ধে প্রস্তাব দেয়
21:25

212

পিছনের দিকে পুনরাবৃত্তি করতে ব্যাপ্তির বিপরীতে ফাংশন প্রয়োগ করুন:

জন্য সুইফট 1.2 এবং তার আগে:

// Print 10 through 1
for i in reverse(1...10) {
    println(i)
}

এটি অর্ধ-খোলা রেঞ্জগুলির সাথেও কাজ করে:

// Print 9 through 1
for i in reverse(1..<10) {
    println(i)
}

দ্রষ্টব্য: reverse(1...10)একটি ধরণের অ্যারে তৈরি করে [Int], তাই এটি ছোট পরিসীমা জন্য উপযুক্ত হতে পারে, lazyনীচে প্রদর্শিত হিসাবে ব্যবহার করা বা strideআপনার পরিসীমা বড় হলে গৃহীত উত্তর বিবেচনা করা বুদ্ধিমানের কাজ হবে ।


একটি বড় অ্যারে তৈরি এড়াতে, lazyপাশাপাশি ব্যবহার করুন reverse()। নীচের পরীক্ষাটি কোনও খেলার মাঠে দক্ষতার সাথে চলে এটি দেখায় যে এটি এক ট্রিলিয়ন Intএস দিয়ে অ্যারে তৈরি করছে না !

টেস্ট:

var count = 0
for i in lazy(1...1_000_000_000_000).reverse() {
    if ++count > 5 {
        break
    }
    println(i)
}

এক্সকোড 7- এ সুইফট ২.০ এর জন্য :

for i in (1...10).reverse() {
    print(i)
}

নোট করুন যে সুইফট ২.০-এ, (1...1_000_000_000_000).reverse()টাইপ ধরণের ReverseRandomAccessCollection<(Range<Int>)>, সুতরাং এটি দুর্দান্ত কাজ করে:

var count = 0
for i in (1...1_000_000_000_000).reverse() {
    count += 1
    if count > 5 {
        break
    }
    print(i)
}

জন্য সুইফট 3.0 reverse() থেকে নাম পরিবর্তন করা হয়েছে reversed():

for i in (1...10).reversed() {
    print(i) // prints 10 through 1
}

3
reversedসংগ্রহটি অনুলিপি করতে পারে, যদিও। অন্ততপক্ষে, আমি কীভাবে ডকুমেন্টেশনটি বুঝি Data
রাফেল

96

সুইফট 3-এর জন্য আপডেট করা হয়েছে

নীচের উত্তরটি উপলব্ধ বিকল্পগুলির সংক্ষিপ্তসার। আপনার প্রয়োজন অনুসারে সবচেয়ে উপযুক্ত একটি নির্বাচন করুন।

reversed: একটি পরিসরে সংখ্যা

অগ্রবর্তী

for index in 0..<5 {
    print(index)
}

// 0
// 1
// 2
// 3
// 4

অনগ্রসর

for index in (0..<5).reversed() {
    print(index)
}

// 4
// 3
// 2
// 1
// 0

reversed: মধ্যে উপাদান SequenceType

let animals = ["horse", "cow", "camel", "sheep", "goat"]

অগ্রবর্তী

for animal in animals {
    print(animal)
}

// horse
// cow
// camel
// sheep
// goat

অনগ্রসর

for animal in animals.reversed() {
    print(animal)
}

// goat
// sheep
// camel
// cow
// horse

reversed: সূচকযুক্ত উপাদান

কখনও কখনও সংগ্রহের মাধ্যমে পুনরাবৃত্তি করার সময় একটি সূচক প্রয়োজন হয়। তার জন্য আপনি ব্যবহার করতে পারেন enumerate(), যা একটি টুপল ফেরত দেয়। টিপলের প্রথম উপাদানটি সূচক এবং দ্বিতীয় উপাদানটি হ'ল অবজেক্ট।

let animals = ["horse", "cow", "camel", "sheep", "goat"]

অগ্রবর্তী

for (index, animal) in animals.enumerated() {
    print("\(index), \(animal)")
}

// 0, horse
// 1, cow
// 2, camel
// 3, sheep
// 4, goat

অনগ্রসর

for (index, animal) in animals.enumerated().reversed()  {
    print("\(index), \(animal)")
}

// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse

নোট করুন যে বেন লাচম্যান তার উত্তরে উল্লেখ করেছেন , আপনি সম্ভবত এর .enumerated().reversed()চেয়ে বেশি করতে চান .reversed().enumerated()(যা সূচকের সংখ্যা বাড়িয়ে তুলবে)।

পদক্ষেপ: সংখ্যা

স্ট্রাইড একটি ব্যাপ্তি ব্যবহার না করে পুনরাবৃত্তি করার উপায়। দুটি রূপ আছে। কোডের শেষে দেওয়া মন্তব্যগুলি পরিসীমা সংস্করণটি কী হবে তা দেখায় (বর্ধিত আকার 1 বলে ধরে নেওয়া)।

startIndex.stride(to: endIndex, by: incrementSize)      // startIndex..<endIndex
startIndex.stride(through: endIndex, by: incrementSize) // startIndex...endIndex

অগ্রবর্তী

for index in stride(from: 0, to: 5, by: 1) {
    print(index)
}

// 0
// 1
// 2
// 3
// 4

অনগ্রসর

বর্ধিত আকার পরিবর্তন করা -1আপনাকে পিছনে যেতে দেয়।

for index in stride(from: 4, through: 0, by: -1) {
    print(index)
}

// 4
// 3
// 2
// 1
// 0

toএবং throughপার্থক্য নোট করুন ।

স্ট্রাইড: সিকোয়েন্সটাইপের উপাদান

2 এর ইনক্রিমেন্ট দ্বারা ফরওয়ার্ড করুন

let animals = ["horse", "cow", "camel", "sheep", "goat"]

আমি 2এই উদাহরণটি ব্যবহার করছি অন্য একটি সম্ভাবনা দেখানোর জন্য।

for index in stride(from: 0, to: 5, by: 2) {
    print("\(index), \(animals[index])")
}

// 0, horse
// 2, camel
// 4, goat

অনগ্রসর

for index in stride(from: 4, through: 0, by: -1) {
    print("\(index), \(animals[index])")
}

// 4, goat
// 3, sheep 
// 2, camel
// 1, cow  
// 0, horse 

মন্তব্য


52

সুইফট 4 এরপরে

for i in stride(from: 5, to: 0, by: -1) {
    print(i)
}
//prints 5, 4, 3, 2, 1

for i in stride(from: 5, through: 0, by: -1) {
    print(i)
}
//prints 5, 4, 3, 2, 1, 0

28

আপনার প্রয়োজন অনুসারে সুইফ্ট 5 এর সাহায্যে আপনার সমস্যা সমাধানের জন্য আপনি নীচের চারটি প্লেগ্রাউন্ড কোড উদাহরণ বেছে নিতে পারেন ।


# 1। ClosedRange reversed()পদ্ধতি ব্যবহার

ClosedRangeএকটি পদ্ধতি বলা হয় reversed()reversed()পদ্ধতির নিম্নলিখিত ঘোষণা রয়েছে:

func reversed() -> ReversedCollection<ClosedRange<Bound>>

বিপরীত ক্রমে সংগ্রহের উপাদানগুলি উপস্থাপন করে এমন একটি দর্শন দেখায়।

ব্যবহার:

let reversedCollection = (0 ... 5).reversed()

for index in reversedCollection {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

বিকল্প হিসাবে, আপনি Range reversed()পদ্ধতিটি ব্যবহার করতে পারেন :

let reversedCollection = (0 ..< 6).reversed()

for index in reversedCollection {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

# 2। sequence(first:next:)ফাংশন ব্যবহার করে

সুইফট স্ট্যান্ডার্ড লাইব্রেরি নামক একটি ফাংশন সরবরাহ করে sequence(first:next:)sequence(first:next:)নিম্নলিখিত ঘোষণা আছে:

func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T>

এর থেকে গঠিত ক্রম firstএবং এর অলস অ্যাপ্লিকেশনগুলি পুনরাবৃত্তি করে next

ব্যবহার:

let unfoldSequence = sequence(first: 5, next: {
    $0 > 0 ? $0 - 1 : nil
})

for index in unfoldSequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

# 3। stride(from:through:by:)ফাংশন ব্যবহার করে

সুইফট স্ট্যান্ডার্ড লাইব্রেরি নামক একটি ফাংশন সরবরাহ করে stride(from:through:by:)stride(from:through:by:)নিম্নলিখিত ঘোষণা আছে:

func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T : Strideable

প্রারম্ভিক মান থেকে সিক্যুয়েন্সটি প্রত্যাবর্তন করে এবং সম্ভবত একটি অন্তর্ভুক্ত মান সহ নির্দিষ্ট পরিমাণে পদক্ষেপ নিয়ে আসে।

ব্যবহার:

let sequence = stride(from: 5, through: 0, by: -1)

for index in sequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

বিকল্প হিসাবে, আপনি ব্যবহার করতে পারেন stride(from:to:by:):

let sequence = stride(from: 5, to: -1, by: -1)

for index in sequence {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

# 4। AnyIterator init(_:)ইনিশিয়ালাইজার ব্যবহার করে

AnyIteratorএকটি ইনিশিয়ালাইজার বলা আছে init(_:)init(_:)নিম্নলিখিত ঘোষণা আছে:

init(_ body: @escaping () -> AnyIterator<Element>.Element?)

একটি পুনরুক্তি তৈরি করে যা প্রদত্ত বন্ধকে তার next()পদ্ধতিতে মোড়ানো ।

ব্যবহার:

var index = 5

guard index >= 0 else { fatalError("index must be positive or equal to zero") }

let iterator = AnyIterator({ () -> Int? in
    defer { index = index - 1 }
    return index >= 0 ? index : nil
})

for index in iterator {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

যদি প্রয়োজন হয়, আপনি পূর্ববর্তী কোডটি পুনরুদ্ধার করতে একটি এক্সটেনশন পদ্ধতি তৈরি করে এতে এতে Intআপনার পুনরুক্তি মোড়ানো করতে পারেন:

extension Int {

    func iterateDownTo(_ endIndex: Int) -> AnyIterator<Int> {
        var index = self
        guard index >= endIndex else { fatalError("self must be greater than or equal to endIndex") }

        let iterator = AnyIterator { () -> Int? in
            defer { index = index - 1 }
            return index >= endIndex ? index : nil
        }
        return iterator
    }

}

let iterator = 5.iterateDownTo(0)

for index in iterator {
    print(index)
}

/*
Prints:
5
4
3
2
1
0
*/

ক্রম (প্রথম: 5, পরবর্তী: {($ 0> 0)? ($ 0 - 1): নীল}) // এর চেয়ে সহজ ($ 0 - 1> = 0)
স্যার ইন্ডার

27

সুইফট ২.০ এবং এর উপরে আপনার বিস্তৃত সংগ্রহের বিপরীতে আবেদন করা উচিত

for i in (0 ..< 10).reverse() {
  // process
}

এটির নাম পরিবর্তন করা হয়েছে। রিভার্সড () এ সুইফট 3.0



5

সুইফট 4.0

for i in stride(from: 5, to: 0, by: -1) {
    print(i) // 5,4,3,2,1
}

আপনি যদি toমানটি অন্তর্ভুক্ত করতে চান :

for i in stride(from: 5, through: 0, by: -1) {
    print(i) // 5,4,3,2,1,0
}

3

যদি কোনও বিপরীতে অ্যারের ( Arrayবা আরও সাধারণভাবে কোনও SequenceType) এর মাধ্যমে পুনরাবৃত্তি করতে চায় । আপনার কাছে কয়েকটি অতিরিক্ত বিকল্প রয়েছে।

প্রথমে আপনি reverse()অ্যারে করতে পারেন এবং এটি স্বাভাবিক হিসাবে লুপ করতে পারেন । তবে আমি enumerate()বেশিরভাগ সময় ব্যবহার করতে পছন্দ করি যেহেতু এটিতে একটি টুপল আউটপুট থাকে এবং এটি সূচক হয়।

এখানে একটি বিষয় লক্ষণীয় হ'ল এগুলি সঠিক ক্রমে কল করা গুরুত্বপূর্ণ:

for (index, element) in array.enumerate().reverse()

অবতরণ ক্রমে সূচকগুলি উত্পাদন করে (যা আমি সাধারণত প্রত্যাশা করি)। যেহেতু:

for (index, element) in array.reverse().enumerate()(যা এনএসআরির সবচেয়ে কাছের ম্যাচ reverseEnumerator)

অ্যারে পিছিয়ে যায় তবে আরোহী সূচকগুলি আউটপুট করে।


3

সুইফট ২.২, এক্সকোড .3.৩ (10, জুন, 2016) হিসাবে:

for (index,number) in (0...10).enumerate() {
    print("index \(index) , number \(number)")
}

for (index,number) in (0...10).reverse().enumerate() {
    print("index \(index) , number \(number)")
}

আউটপুট:

index 0 , number 0
index 1 , number 1
index 2 , number 2
index 3 , number 3
index 4 , number 4
index 5 , number 5
index 6 , number 6
index 7 , number 7
index 8 , number 8
index 9 , number 9
index 10 , number 10


index 0 , number 10
index 1 , number 9
index 2 , number 8
index 3 , number 7
index 4 , number 6
index 5 , number 5
index 6 , number 4
index 7 , number 3
index 8 , number 2
index 9 , number 1
index 10 , number 0

2

আপনি whileপরিবর্তে সি স্টাইল লুপ ব্যবহার বিবেচনা করতে পারেন । এটি সুইফট 3 এ কেবল সূক্ষ্মভাবে কাজ করে:

var i = 5 
while i > 0 { 
    print(i)
    i -= 1
}

2

আপনি সহজেই বিপরীত মানগুলির জন্য বিপরীত () পদ্ধতিটি ব্যবহার করতে পারেন।

var i:Int
for i in 1..10.reversed() {
    print(i)
}

বিপরীত () পদ্ধতিটি মানগুলিকে বিপরীত করে।


আপনি কেন ইতিমধ্যে বিদ্যমান একটির মতো একটি উত্তর যুক্ত করবেন? (উদাহরণস্বরূপ, @ রোহিতের।)
19:30 এ কিউবারিকের পছন্দ পছন্দ করুন

1
var sum1 = 0
for i in 0...100{
    sum1 += i
}
print (sum1)

for i in (10...100).reverse(){
    sum1 /= i
}
print(sum1)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.