কীভাবে সুইফটে রেঞ্জ তৈরি করবেন?


103

উদ্দেশ্য-সিতে আমরা এনএসআরঞ্জ ব্যবহার করে ব্যাপ্তি তৈরি করি

NSRange range;

তাহলে কীভাবে সুইফটে রেঞ্জ তৈরি করবেন?


3
আপনার পরিসীমাটি কী দরকার? সুইফ্ট স্ট্রিংগুলি ব্যবহার করে Range<String.Index>তবে কখনও কখনও এটির সাথে কাজ করা প্রয়োজন NSStringএবং NSRangeতাই আরও কিছু প্রসঙ্গ দরকারী। - তবে স্ট্যাকওভারফ্লো . com/ জিজ্ঞাসাগুলি / ২৪৪০২৮৮৪৮/২ দেখুন
মার্টিন আর

উত্তর:


256

সুইফট 4-র জন্য আপডেট হয়েছে

সুইফট রেঞ্জগুলি আরও জটিল NSRangeএবং সুইফট ৩ এ এগুলি সহজতর কিছু পায় নি যদি আপনি এই জটিলতার কিছুটির পিছনে যুক্তি বোঝার চেষ্টা করতে চান তবে এটি এবং এটি পড়ুন । এগুলি কীভাবে তৈরি করা যায় এবং আপনি কখন সেগুলি ব্যবহার করতে পারেন তা আমি আপনাকে কেবল দেখাব।

বন্ধ রেঞ্জ: a...b

এই ব্যাপ্তি অপারেটর একটি সুইফট পরিসর তৈরি করে যার মধ্যে উপাদান a এবং উপাদান উভয়ই অন্তর্ভুক্ত bথাকে, এমনকি যদি bকোনও ধরণের (পছন্দ মতো Int.max) সর্বাধিক সম্ভাব্য মান হয় । দুটি ধরণের বন্ধ রেঞ্জ রয়েছে: ClosedRangeএবংCountableClosedRange

1। ClosedRange

সুইফ্টের সমস্ত ব্যাপ্তির উপাদানগুলি তুলনামূলক (যেমন, তারা তুলনীয় প্রোটোকলের সাথে সঙ্গতিপূর্ণ)। এটি আপনাকে সংগ্রহ থেকে রেঞ্জের উপাদানগুলিকে অ্যাক্সেস করতে দেয়। এখানে একটি উদাহরণ:

let myRange: ClosedRange = 1...3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

তবে, একটি ClosedRangeগণনাযোগ্য নয় (যেমন, এটি সিকোয়েন্স প্রোটোকলের সাথে সম্মতি দেয় না)। এর অর্থ আপনি forলুপ দিয়ে উপাদানগুলির উপর পুনরাবৃত্তি করতে পারবেন না । যে আপনি প্রয়োজন জন্য CountableClosedRange

2। CountableClosedRange

এটি এখনকার ব্যতীত শেষের মতো, পরিসীমাটিও পুনরাবৃত্তি হতে পারে।

let myRange: CountableClosedRange = 1...3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c", "d"]

for index in myRange {
    print(myArray[index])
}

অর্ধ-খোলা রেঞ্জ: a..<b

এই পরিসীমা অপারেটর উপাদান অন্তর্ভুক্ত aকিন্তু না উপাদান b। উপরের মতো, দুটি পৃথক ধরণের অর্ধ-খোলা রেঞ্জ রয়েছে: RangeএবংCountableRange

1। Range

হিসাবে ClosedRange, আপনি একটি দিয়ে সংগ্রহের উপাদানগুলি অ্যাক্সেস করতে পারেন Range। উদাহরণ:

let myRange: Range = 1..<3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

আবার, যদিও আপনি a এর উপর পুনরাবৃত্তি করতে পারবেন না Range কোনওটি কারণ এটি কেবল তুলনীয়, স্ট্রাইড নয়।

2। CountableRange

CountableRangeপুনরাবৃত্তির অনুমতি দেয়।

let myRange: CountableRange = 1..<3

let myArray = ["a", "b", "c", "d", "e"]
myArray[myRange] // ["b", "c"]

for index in myRange {
    print(myArray[index])
}

NSRange

আপনি (অবশ্যই) এখনও NSRangeসময়ে সময়ে সুইফট ব্যবহার করতে পারেন ( যেমন বিশিষ্ট স্ট্রিংগুলি তৈরি করার সময় ), সুতরাং এটি কীভাবে তৈরি করা যায় তা জানার জন্য সহায়ক।

let myNSRange = NSRange(location: 3, length: 2)

মনে রাখবেন যে এটি অবস্থান এবং দৈর্ঘ্য , সূচক এবং শেষ সূচক নয়। এখানে উদাহরণটি সুইফ্ট পরিসরের সাথে একই রকম 3..<5। তবে, যেহেতু প্রকারগুলি পৃথক, সেগুলি বিনিময়যোগ্য নয়।

স্ট্রিং সহ রেঞ্জ

...এবং ..<পরিসীমা অপারেটার রেঞ্জ তৈরি করার একটি সাঁটে লেখার উপায়। উদাহরণ স্বরূপ:

let myRange = 1..<3

একই পরিসীমা তৈরির দীর্ঘ হাতের পথ হবে

let myRange = CountableRange<Int>(uncheckedBounds: (lower: 1, upper: 3)) // 1..<3

আপনি দেখতে পাচ্ছেন যে এখানে সূচক টাইপ রয়েছে IntStringযদিও এটি কার্যকর হয় না , কারণ স্ট্রিংগুলি অক্ষর দ্বারা তৈরি এবং সমস্ত অক্ষর একই আকার নয়। (পড়ুন এই আরও তথ্যের জন্য।) মত 😀 একটি ইমোজি, উদাহরণস্বরূপ, চিঠি "B" চেয়ে আরও জায়গা লাগে।

এনএসরেঞ্জের সাথে সমস্যা

ইমোজি সহ NSRangeএকটি পরীক্ষা করার চেষ্টা করুন NSStringএবং আপনি কী বোঝাতে চাইবেন তা আপনি দেখতে পাবেন। মাথা ব্যাথা।

let myNSRange = NSRange(location: 1, length: 3)

let myNSString: NSString = "abcde"
myNSString.substring(with: myNSRange) // "bcd"

let myNSString2: NSString = "a😀cde"
myNSString2.substring(with: myNSRange) // "😀c"    Where is the "d"!?

হাসিখুশি মুখ দুটি ইউটিএফ -16 কোড ইউনিট নেয়, সুতরাং এটি "ডি" অন্তর্ভুক্ত না করার অপ্রত্যাশিত ফলাফল দেয়।

সুইফট সলিউশন

এর কারণে, আপনি যে সুইফট স্ট্রিংগুলি ব্যবহার করেন Range<String.Index>তা নয় Range<Int>। স্ট্রিং সূচকটি একটি নির্দিষ্ট স্ট্রিংয়ের উপর ভিত্তি করে গণনা করা হয় যাতে এটি জানতে পারে যে কোনও ইমোজি বা বর্ধিত গ্রাফি ক্লাস্টার রয়েছে কিনা।

উদাহরণ

var myString = "abcde"
let start = myString.index(myString.startIndex, offsetBy: 1)
let end = myString.index(myString.startIndex, offsetBy: 4)
let myRange = start..<end
myString[myRange] // "bcd"

myString = "a😀cde"
let start2 = myString.index(myString.startIndex, offsetBy: 1)
let end2 = myString.index(myString.startIndex, offsetBy: 4)
let myRange2 = start2..<end2
myString[myRange2] // "😀cd"

একতরফা রেঞ্জ: a...এবং ...bএবং..<b

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

int

সংগ্রহের মাধ্যমে পুনরাবৃত্তি করতে আপনি একতরফা পূর্ণসংখ্যার ব্যাপ্তি ব্যবহার করতে পারেন। এখানে ডকুমেন্টেশন থেকে কিছু উদাহরণ দেওয়া আছে ।

// iterate from index 2 to the end of the array
for name in names[2...] {
    print(name)
}

// iterate from the beginning of the array to index 2
for name in names[...2] {
    print(name)
}

// iterate from the beginning of the array up to but not including index 2
for name in names[..<2] {
    print(name)
}

// the range from negative infinity to 5. You can't iterate forward
// over this because the starting point in unknown.
let range = ...5
range.contains(7)   // false
range.contains(4)   // true
range.contains(-1)  // true

// You can iterate over this but it will be an infinate loop 
// so you have to break out at some point.
let range = 5...

দড়ি

এটি স্ট্রিং রেঞ্জগুলির সাথেও কাজ করে। আপনি যদি এক প্রান্তে str.startIndexবা এর সাথে একটি পরিসীমা তৈরি করে থাকেন তবে আপনি str.endIndexএটিকে ছেড়ে দিতে পারেন। সংকলক এটি অনুমান করা হবে।

প্রদত্ত

var str = "Hello, playground"
let index = str.index(str.startIndex, offsetBy: 5)

let myRange = ..<index    // Hello

আপনি ব্যবহার করে সূচক থেকে str.endIndex এ যেতে পারেন ...

var str = "Hello, playground"
let index = str.index(str.endIndex, offsetBy: -10)
let myRange = index...        // playground

আরো দেখুন:

মন্তব্য

  • আপনি আলাদা স্ট্রিংয়ের একটি স্ট্রিং দিয়ে আপনি তৈরি রেঞ্জটি ব্যবহার করতে পারবেন না।
  • যেমন আপনি দেখতে পাচ্ছেন, স্ট্রিং রেঞ্জগুলি সুইফটে একটি ব্যথা, তবে তারা ইমোজি এবং অন্যান্য ইউনিকোড স্কেলারের সাথে আরও ভাল আচরণ করতে পারে।

আরও অধ্যয়ন


আমার মন্তব্যটি "এনএসরেঞ্জের সাথে সমস্যা" উপধারা সম্পর্কিত। NSStringঅভ্যন্তরীণভাবে ইউটিএফ -16 এনকোডিংয়ে এর অক্ষরগুলি সঞ্চয় করে। একটি সম্পূর্ণ ইউনিকোড স্কেলারটি 21-বিট। গ্রিনিং ফেস ক্যারেক্টার ( U+1F600) একক 16-বিট কোড ইউনিটে সংরক্ষণ করা যায় না, সুতরাং এটি 2 টির মধ্যে ছড়িয়ে আছে NSRange16 বিট কোড ইউনিটের উপর ভিত্তি করে গণনা। এই উদাহরণস্বরূপ, 3 কোড ইউনিট কেবল 2 টি অক্ষরের প্রতিনিধিত্ব করতে পারে
কোড ভিন্ন ভিন্ন

25

এক্সকোড 8 বিটা 2 • সুইফট 3

let myString = "Hello World"
let myRange = myString.startIndex..<myString.index(myString.startIndex, offsetBy: 5)
let mySubString = myString.substring(with: myRange)   // Hello

এক্সকোড 7 • সুইফট 2.0

let myString = "Hello World"
let myRange = Range<String.Index>(start: myString.startIndex, end: myString.startIndex.advancedBy(5))

let mySubString = myString.substringWithRange(myRange)   // Hello

বা সহজভাবে

let myString = "Hello World"
let myRange = myString.startIndex..<myString.startIndex.advancedBy(5)
let mySubString = myString.substringWithRange(myRange)   // Hello


2

এই মত ব্যবহার করুন

var start = str.startIndex // Start at the string's start index
var end = advance(str.startIndex, 5) // Take start index and advance 5 characters forward
var range: Range<String.Index> = Range<String.Index>(start: start,end: end)

let firstFiveDigit =  str.substringWithRange(range)

print(firstFiveDigit)

আউটপুট: হ্যালো


আমি দেখতে পাচ্ছি তাদের "রেঞ্জ" ডেটাটাইপ রয়েছে। তাহলে আমি কীভাবে এটি ব্যবহার করতে পারি?
বিছাই

@ বিছাই আপনি যেখানে ব্যবহার করতে চান সেখানে আরও বিস্তারিত বর্ণনা করতে পারেন?
ধর্মবীর সিং

উদ্দেশ্য মত সি: এনএসরেঞ্জ পরিসীমা;
বিচাই

1

আমি অবাক করে দিয়েছি যে, এমনকি সুইফট 4-এ, ইন্ট ব্যবহার করে স্ট্রিং রেঞ্জটি প্রকাশ করার মতো সহজ কোনও নেটিভ উপায় নেই। কেবলমাত্র স্ট্রিং পদ্ধতিগুলি আপনাকে পরিসীমা অনুসারে একটি স্ট্রিংগুলি পাওয়ার উপায় হিসাবে কোনও ইন্টার সরবরাহ করতে দেয় prefixএবং সেগুলি suffix

কিছু রূপান্তর ইউটিলিটি হাতে রাখা দরকারী, যাতে কোনও স্ট্রিংয়ের সাথে কথা বলার সময় আমরা এনএসরেঞ্জের মতো কথা বলতে পারি। এখানে একটি ইউটিলিটি যা NSRange এর মতো একটি অবস্থান এবং দৈর্ঘ্য গ্রহণ করে এবং একটি ফেরত দেয় Range<String.Index>:

func range(_ start:Int, _ length:Int) -> Range<String.Index> {
    let i = self.index(start >= 0 ? self.startIndex : self.endIndex,
        offsetBy: start)
    let j = self.index(i, offsetBy: length)
    return i..<j
}

উদাহরণস্বরূপ, "hello".range(0,1)"হয় Range<String.Index>প্রথম অক্ষরটি আলিঙ্গন "hello"। একটি বোনাস হিসেবে আমি নেতিবাচক অবস্থানে অনুমতি করেছি: "hello".range(-1,1)"হয় Range<String.Index>নামের শেষ অক্ষরটি আলিঙ্গন "hello"

Range<String.Index>কোনও এনএসআরঞ্জে রূপান্তরিত করাও দরকারী , সেই মুহুর্তগুলির জন্য যখন আপনাকে কোকোয়ের সাথে কথা বলতে হবে (উদাহরণস্বরূপ, এনএস্যাট্রিবিউটেড স্ট্রিং অ্যাট্রিবিউট রেঞ্জগুলি নিয়ে কাজ করার ক্ষেত্রে)। সুইফট 4 এটি করার একটি স্থানীয় উপায় সরবরাহ করে:

let nsrange = NSRange(range, in:s) // where s is the string

আমরা এইভাবে আরও একটি ইউটিলিটি লিখতে পারি যেখানে আমরা স্ট্রিংয়ের অবস্থান এবং দৈর্ঘ্য থেকে সরাসরি এনএসরেঞ্জে যাই:

extension String {
    func nsRange(_ start:Int, _ length:Int) -> NSRange {
        return NSRange(self.range(start,length), in:self)
    }
}

1

যদি কেউ এনএসআরঞ্জ বস্তু তৈরি করতে চান তবে এটি তৈরি করতে পারেন:

let range: NSRange = NSRange.init(location: 0, length: 5)

এটি পজিশন 0 এবং দৈর্ঘ্য 5 সহ সীমা তৈরি করবে


0

আমি নিম্নলিখিত এক্সটেনশনটি তৈরি করেছি:

extension String {
    func substring(from from:Int, to:Int) -> String? {
        if from<to && from>=0 && to<self.characters.count {
            let rng = self.startIndex.advancedBy(from)..<self.startIndex.advancedBy(to)
            return self.substringWithRange(rng)
        } else {
            return nil
        }
    }
}

ব্যবহারের উদাহরণ:

print("abcde".substring(from: 1, to: 10)) //nil
print("abcde".substring(from: 2, to: 4))  //Optional("cd")
print("abcde".substring(from: 1, to: 0))  //nil
print("abcde".substring(from: 1, to: 1))  //nil
print("abcde".substring(from: -1, to: 1)) //nil

0

আপনি এটি ব্যবহার করতে পারেন

let nsRange = NSRange(location: someInt, length: someInt)

হিসাবে হিসাবে

let myNSString = bigTOTPCode as NSString //12345678
let firstDigit = myNSString.substringWithRange(NSRange(location: 0, length: 1)) //1
let secondDigit = myNSString.substringWithRange(NSRange(location: 1, length: 1)) //2
let thirdDigit = myNSString.substringWithRange(NSRange(location: 2, length: 4)) //3456

0

আমি এটা করতে চাই:

print("Hello"[1...3])
// out: Error

তবে দুর্ভাগ্যক্রমে, আমি আমার নিজের একটি সাবস্ক্রিপ্ট লিখতে পারি না কারণ घृणाধারী ব্যক্তি নামের জায়গা নেয়।

আমরা তবে এটি করতে পারি:

print("Hello"[range: 1...3])
// out: ell 

আপনার প্রকল্পে এটি কেবল যুক্ত করুন:

extension String {
    subscript(range: ClosedRange<Int>) -> String {
        get {
            let start = String.Index(utf16Offset: range.lowerBound, in: self)
            let end = String.Index(utf16Offset: range.upperBound, in: self)
            return String(self[start...end])
        }
    }
}

0
func replace(input: String, start: Int,lenght: Int, newChar: Character) -> String {
    var chars = Array(input.characters)

    for i in start...lenght {
        guard i < input.characters.count else{
            break
        }
        chars[i] = newChar
    }
    return String(chars)
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.