সুইফটে বিপরীত রেঞ্জ


105

সুইফটে বিপরীত রেঞ্জগুলির সাথে কাজ করার কোনও উপায় আছে?

উদাহরণ স্বরূপ:

for i in 5...1 {
  // do something
}

একটি অসীম লুপ।

সুইফ্টের নতুন সংস্করণগুলিতে কোডটি সংকলন করে তবে রানটাইম এ ত্রুটি দেয়:

মারাত্মক ত্রুটি: আপারবাউন্ড <লোয়ারবাউন্ডের সাথে ব্যাপ্তি তৈরি করা যায় না

আমি জানি আমি 1..5পরিবর্তে ব্যবহার করতে পারি , গণনা j = 6 - iকরতে jএবং আমার সূচক হিসাবে ব্যবহার করতে পারি। আমি ভাবছিলাম কি আরও সুস্পষ্ট কিছু আছে?


অনুরূপ প্রশ্নের জন্য আমার উত্তরটি দেখুন যা সুইফট 3 দিয়ে আপনার সমস্যা সমাধানের জন্য 8 টি উপায় দেয়
Imanou Petit

উত্তর:


184

সর্বশেষতম সুইফ্ট 3 এর জন্য আপডেট করুন (এখনও সুইফট 4 এ কাজ করে)

আপনি reversed()একটি ব্যাপ্তিতে পদ্ধতিটি ব্যবহার করতে পারেন

for i in (1...5).reversed() { print(i) } // 5 4 3 2 1

বা stride(from:through:by:)পদ্ধতি

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

stide(from:to:by:) অনুরূপ তবে শেষ মানটি বাদ দেয়

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

সর্বশেষতম সুইফট 2 এর জন্য আপডেট

প্রথমত, প্রোটোকল এক্সটেনশানগুলি কীভাবে reverseব্যবহৃত হয় তা পরিবর্তন করে :

for i in (1...5).reverse() { print(i) } // 5 4 3 2 1

এক্সকোড 7 বিটা 6 এ স্ট্রাইড পুনরায় কাজ করা হয়েছে নতুন ব্যবহারটি হ'ল:

for i in 0.stride(to: -8, by: -2) { print(i) } // 0 -2 -4 -6
for i in 0.stride(through: -8, by: -2) { print(i) } // 0 -2 -4 -6 -8

এটি এর জন্যও কাজ করে Doubles:

for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }

সীমানার জন্য এখানে ভাসমান পয়েন্টের তুলনায় সতর্ক থাকুন।

সুইফট ১.২ এর জন্য পূর্ববর্তী সম্পাদনা : এক্সকোড 6 বিটা 4 হিসাবে, বাই এবং রিভার্সরেঞ্জের আর অস্তিত্ব নেই: [

আপনি যদি কেবল কোনও ব্যাপ্তির বিপরীত দিকে তাকিয়ে থাকেন তবে বিপরীত কার্যটি আপনার যা প্রয়োজন তা হ'ল:

for i in reverse(1...5) { println(i) } // prints 5,4,3,2,1

0x7fffffff পোস্ট হিসাবে একটি নতুন স্ট্রাইড কন্সট্রাক্ট আছে যা পুনরাবৃত্তি করতে এবং স্বেচ্ছাচারিত পূর্ণসংখ্যার সাহায্যে বৃদ্ধি করতে ব্যবহার করা যেতে পারে। অ্যাপল আরও জানিয়েছে যে ভাসমান পয়েন্ট সমর্থন আসছে।

তার উত্তর থেকে উত্সাহিত:

for x in stride(from: 0, through: -8, by: -2) {
    println(x) // 0, -2, -4, -6, -8
}

for x in stride(from: 6, to: -2, by: -4) {
    println(x) // 6, 2
}

এফওয়াইআই স্ট্রাইডটি বিটা 6
ডগকফি

1
এটি হওয়া উচিত (1...5).reverse()(একটি ফাংশন কল হিসাবে), দয়া করে আপনার উত্তর আপডেট করুন। (যেহেতু এটি কেবলমাত্র দুটি অক্ষর, তাই আমি আপনার পোস্ট সম্পাদনা করতে পারিনি))
বাহাদাদ

সুইফট 3.0-পূর্বদর্শন -4 (এবং সম্ভবত পূর্বে) এটি হওয়া উচিত (1...5).reversed()। এছাড়াও, উদাহরণটি .stride()কাজ করে না এবং এর stride(from:to:by:)পরিবর্তে ফ্রি ফাংশন প্রয়োজন ।
ডেভিডা

2
মনে হচ্ছে strideসুইফট 3 এর কোডটি কিছুটা ভুল। নম্বর 1 টি অন্তর্ভুক্ত করার জন্য, আপনাকে এই throughtofor i in stride(from:5,through:1,by:-1) { print(i) }
মতগুলির

4
এটি reversedO (1) এর জটিলতা রয়েছে তা উল্লেখ করার মতো কারণ এটি কেবলমাত্র মূল সংগ্রহটি আবৃত করে এবং এটি তৈরি করতে পুনরাবৃত্তির প্রয়োজন হয় না।
devios1

21

এর অসম্পূর্ণতা নিয়ে ঝামেলা করার মতো কিছু আছে:

for i in (1..<5).reverse()

... এর বিপরীতে:

for i in 1..<5 {

এর অর্থ হ'ল প্রতিবার আমি বিপরীত পরিসীমা করতে চাইলে আমাকে প্রথম বন্ধনী লিখতে হবে, এবং আমাকে .reverse()শেষের দিকে লিখতে হবে , ঘাড়ে থাম্বের মতো লেগে থাকবে। লুপগুলির জন্য সি-স্টাইলের তুলনায় এটি সত্যিই কুশ্রী, যা প্রতিসম অঙ্ক এবং গণনা সমান্তরাল counting সুতরাং আমি পরিবর্তে লুপগুলির জন্য সি-স্টাইল ব্যবহার করার ঝোঁক রেখেছিলাম। তবে সুইফট ২.২-এ, লুপগুলির জন্য সি-স্টাইলটি চলে যাচ্ছে! সুতরাং আমাকে এই কুরুচিপূর্ণ .reverse()নির্মাণের সাথে লুপগুলির জন্য আমার সমস্ত হ্রাসমান সি-স্টাইল প্রতিস্থাপনের আশেপাশে ছটফট করতে হয়েছিল - সবসময় ভাবছি, পৃথিবীতে কেন কোনও বিপরীত-পরিসীমা অপারেটর নেই?

কিন্তু অপেক্ষা করো! এটি সুইফট - আমাদের নিজস্ব অপারেটরগুলি সংজ্ঞায়িত করার অনুমতি দেওয়া হয় !! এখানে আমরা যাচ্ছি:

infix operator >>> {
    associativity none
    precedence 135
}

func >>> <Pos : ForwardIndexType where Pos : Comparable>(end:Pos, start:Pos)
    -> ReverseRandomAccessCollection<(Range<Pos>)> {
        return (start..<end).reverse()
}

সুতরাং এখন আমাকে বলতে অনুমতি দেওয়া হয়েছে:

for i in 5>>>1 {print(i)} // 4, 3, 2, 1

এই কভার শুধু সবচেয়ে সাধারণ ক্ষেত্রে যে আমার কোড ঘটে, কিন্তু এটা হয় অনেক দূরে সবচেয়ে সাধারণ ক্ষেত্রে, তাই এটি বর্তমানে আমি প্রয়োজন নেই।

অপারেটরের সাথে আমার এক ধরণের অভ্যন্তরীণ সংকট দেখা দিয়েছে। আমি >..এর বিপরীত হিসাবে ব্যবহার করতে পছন্দ করতাম ..<, তবে এটি আইনী নয়: আপনি বিন্দুর পরে বিন্দু ব্যবহার করতে পারবেন না, এটি প্রদর্শিত হবে। আমি বিবেচনা করেছি ..>কিন্তু সিদ্ধান্ত নিয়েছি এটির থেকে পার্থক্য করা খুব কঠিন ..<। সুন্দর জিনিসটি >>>এটি আপনাকে দেখে চিৎকার করে: " ডাউন টু!" (অবশ্যই আপনি অন্য অপারেটরের সাথে আসতে পারেন But তবে আমার পরামর্শটি হ'ল সুপার প্রতিসাম্যের জন্য, <<<যা ..<করে তা করার জন্য সংজ্ঞা দিন এবং এখন আপনি পেয়েছেন <<<এবং >>>যা প্রতিসম ও টাইপ করা সহজ)


সুইফট 3 সংস্করণ (এক্সকোড 8 বীজ 6):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound) ->
    ReversedRandomAccessCollection<CountableRange<Bound>> 
    where Bound : Comparable, Bound.Stride : Integer {
        return (minimum..<maximum).reversed()
}

সুইফট 4 সংস্করণ (এক্সকোড 9 বিটা 3):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedRandomAccessCollection<CountableRange<Bound>>
    where Bound : Comparable & Strideable { 
        return (minimum..<maximum).reversed()
}

সুইফট 4.2 সংস্করণ (এক্সকোড 10 বিটা 1):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedRandomAccessCollection<Range<Bound>>
    where Bound : Strideable { 
        return (minimum..<maximum).reversed()
}

সুইফ্ট 5 সংস্করণ (এক্সকোড 10.2.1):

infix operator >>> : RangeFormationPrecedence
func >>><Bound>(maximum: Bound, minimum: Bound)
    -> ReversedCollection<Range<Bound>>
    where Bound : Strideable {
        return (minimum..<maximum).reversed()
}

1
বাহ, >>>অপারেটরটি আসলেই দুর্দান্ত! আমি আশা করি সুইফ্ট ডিজাইনাররা সেই জাতীয় জিনিসের প্রতি মনোযোগ দিন, কারণ প্রথম বন্ধুত্বপূর্ণ reverse()এক্সপ্রেশনগুলির উপর স্টিক করা অদ্ভুত বোধ করে। তারা 5>..0স্বয়ংক্রিয়ভাবে ব্যাপ্তিগুলির সাথে ডিল করতে পারে না এমন কোনও কারণ নেই , কারণ ForwardIndexTypeপ্রোটোকল একটি নিখুঁত যুক্তিসঙ্গত distanceTo()অপারেটর সরবরাহ করে যা ধাপে ধনাত্মক বা negativeণাত্মক হওয়া উচিত কিনা তা নির্ধারণ করতে ব্যবহার করা যেতে পারে।
dasblinkenlight

1
ধন্যবাদ @ ড্যাসব্লিংকনলাইট - এটি আমার জন্য উপস্থিত হয়েছিল কারণ আমার একটি অ্যাপ্লিকেশনটিতে আমার কাছে লুপগুলির জন্য প্রচুর সি ছিল (অবজেক্টিভ-সি) লুপগুলির জন্য সুইফট সি-স্টাইলে স্থানান্তরিত হয়েছিল এবং এখন রূপান্তর করতে হয়েছিল কারণ লুপগুলির জন্য সি-স্টাইল চলে যাচ্ছে এটি কেবল ভয়াবহ ছিল, কারণ এই লুপগুলি আমার অ্যাপ্লিকেশনটির যুক্তির মূল অংশকে উপস্থাপন করে এবং সবকিছুকে পুনরায় লেখার ফলে ভাঙ্গনের ঝুঁকি ছিল। সুতরাং আমি একটি স্বরলিপি চেয়েছিলাম যা (কমেন্ট-আউট) সি-স্টাইলের স্বরলিপিটি যতটা সম্ভব স্পষ্ট করে তুলবে।
ম্যাট

ঝরঝরে! আমি আপনার ক্লিন লুকিং কোডের সাথে আবেশ পছন্দ করি!
ইয়াহস্ট

10

দেখা যাচ্ছে যে আমরা বিটার মাধ্যমে অগ্রসর হওয়ার সাথে সাথে এই প্রশ্নের উত্তরগুলি কিছুটা পরিবর্তিত হয়েছে। বিটা 4 হিসাবে, by()ফাংশন এবং ReversedRangeপ্রকার উভয়ই ভাষা থেকে সরানো হয়েছে। যদি আপনি একটি বিপরীত পরিসীমা তৈরি করতে চাইছেন তবে আপনার বিকল্পগুলি এখন নীচে রয়েছে:

1: একটি ফরোয়ার্ড সীমা তৈরি করুন এবং তারপরে reverse()এটির বিপরীতে ফাংশনটি ব্যবহার করুন ।

for x in reverse(0 ... 4) {
    println(x) // 4, 3, 2, 1, 0
}

for x in reverse(0 ..< 4) {
    println(x) // 3, 2, 1, 0
}

2: stride()বিটা 4 এ যুক্ত হওয়া নতুন ফাংশনগুলি ব্যবহার করুন , যার সূচনা এবং সমাপ্তি সূচকগুলি নির্দিষ্ট করার জন্য ফাংশন এবং সেই সাথে পুনরাবৃত্তির পরিমাণও অন্তর্ভুক্ত রয়েছে।

for x in stride(from: 0, through: -8, by: -2) {
    println(x) // 0, -2, -4, -6, -8
}

for x in stride(from: 6, to: -2, by: -4) {
    println(x) // 6, 2
}

মনে রাখবেন যে আমি এই পোস্টে নতুন এক্সক্লুসিভ রেঞ্জ অপারেটরটিকেও অন্তর্ভুক্ত করেছি। ..সঙ্গে প্রতিস্থাপন করা হয়েছিল ..<

সম্পাদনা করুন: এক্সকোড 6 বিটা 5 রিলিজ নোটগুলি থেকে , অ্যাপল এটি পরিচালনা করার জন্য নিম্নলিখিত পরামর্শ যুক্ত করেছে:

রিভার্সরেঞ্জ সরানো হয়েছে; অলস ব্যবহার করুন (এক্স ..

এখানে একটি উদাহরণ।

for i in lazy(0...5).reverse() {
    // 0, 1, 2, 3, 4, 5
}

+1 আমি একটি রেফারেন্স খুঁজছি lazy(0....5).reverse()এবং আমি বিটা 5 রিলিজ নোট দেখতে পাচ্ছি না। আপনি কি এই বিষয়ে অন্যান্য আলোচনা সম্পর্কে জানেন? এছাড়াও, এফওয়াইআই, সেই forলুপের ভিতরে থাকা নম্বরগুলি আপনার উদাহরণে পিছনের দিকে।
রব

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

1
@ 0x7fffffff আপনার শেষ উদাহরণে, মন্তব্যটি বলেছে // 0, 1, 2, 3, 4, 5তবে এটি আসলে বিপরীত হওয়া উচিত। মন্তব্যটি বিভ্রান্তিকর।
পাং


3

সুইফট 3, 4+ : আপনি এটি এর মতো করতে পারেন:

for i in sequence(first: 10, next: {$0 - 1}) {

    guard i >= 0 else {
        break
    }
    print(i)
}

ফলাফল : 10, 9, 8 ... 0

আপনি নিজের পছন্দমত যেকোন উপায়ে কাস্টমাইজ করতে পারেন। আরও তথ্যের জন্য পড়ুন func sequence<T>রেফারেন্স



-2

বিপরীত সংখ্যার জন্য বিপরীত () ফাংশন ব্যবহৃত হয়।

ভার এন: ইন্ট // নম্বর লিখুন

আমি 1 এ ... n বিপরীত () {মুদ্রণ (i)}

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