সুইফ্ট প্রোগ্রামিং ভাষায় একটি স্ট্রিংয়ের নবম অক্ষর পান


419

আমি কীভাবে একটি স্ট্রিংয়ের নবম চরিত্র পেতে পারি? আমি []কোনও ভাগ্য ছাড়াই বন্ধনী ( ) অ্যাক্সেসরের চেষ্টা করেছি ।

var string = "Hello, world!"

var firstChar = string[0] // Throws error

ত্রুটি: 'সাবস্ক্রিপ্ট' অনুপলব্ধ: কোনও ইন্টার সহ স্ট্রিং সাবস্ক্রিপ্ট করতে পারে না, আলোচনার জন্য ডকুমেন্টেশন মন্তব্যটি দেখুন


1
ত্রুটি বার্তা "আলোচনার জন্য ডকুমেন্টেশন মন্তব্য দেখুন, কোনও ইন্টার এর সাথে স্ট্রিংক্রিপশন
অ্যান্ড্রুডটনে

var firstChar = string.index(string.startIndex, offsetBy: 0)পরিবর্তে ব্যবহার করুন
সাজ্জাদ হিশাইন খান

@ সাজ্জাদহিসাইন খান এর ফলে একটি অক্ষর নয়, একটি স্ট্রিং সূচক তৈরি হবে। বিটিডব্লু কেন সহজভাবে নয় string.startIndex? প্রথম চরিত্রের জন্য string[string.startIndex] বা সহজভাবে string.first। নোট করুন যে স্ট্রিংটি খালি আছে তা আপনাকে প্রথমে পরীক্ষা করতে হবে দ্বিতীয়টি
alচ্ছিক

উত্তর:


567

মনোযোগ দিন: দয়া করে সুইফট 4 এবং সুইফট 5-র জন্য যথাযথ প্রয়োগের জন্য লিও ডাবসের উত্তর দেখুন ।

4 বা তারপরে সুইফট করুন

Substringটাইপ সুইফট 4 চালু হয়, সাবস্ট্রিং দ্রুত ও আরও কার্যকর মূল স্ট্রিং সঙ্গে স্টোরেজ ভাগ করে করা, যাতে এটা কি সাবস্ক্রিপ্ট ফাংশন ফেরত পাঠাবেন।

এখানে চেষ্টা করে দেখুন

extension StringProtocol {
    subscript(offset: Int) -> Character { self[index(startIndex, offsetBy: offset)] }
    subscript(range: Range<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let startIndex = index(self.startIndex, offsetBy: range.lowerBound)
        return self[startIndex..<index(startIndex, offsetBy: range.count)]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence { self[index(startIndex, offsetBy: range.lowerBound)...] }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence { self[...index(startIndex, offsetBy: range.upperBound)] }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence { self[..<index(startIndex, offsetBy: range.upperBound)] }
}

এটিকে রূপান্তর করতে, আপনি কেবলমাত্র এটি করতে পারেন , তবে আপনি যদি কেবল স্ট্রিংগুলি প্রায় রাখার পরিকল্পনা করেন তবে আপনার কেবল এটি Substringকরা উচিত। অন্যথায়, এটি এটি রাখা আরও দক্ষ ।StringString(string[0..2])Substring

এই দুটি এক্সটেনশানটিকে একটিতে একীভূত করার জন্য যদি কেউ ভাল উপায় বের করতে পারে তবে এটি দুর্দান্ত be আমি StringProtocol সাফল্য ছাড়াই প্রসারিত করার চেষ্টা করেছি , কারণ indexপদ্ধতিটি এখানে নেই। দ্রষ্টব্য: এই উত্তরটি ইতিমধ্যে সম্পাদিত হয়েছে, এটি সঠিকভাবে প্রয়োগ করা হয়েছে এবং এখন সাবস্ট্রিংয়ের জন্যও কাজ করে। আপনার স্ট্রিংপ্রোটোকল ধরণের সাবস্ক্রিপশন করার সময় ক্রাশ হওয়া এড়াতে কেবল একটি বৈধ পরিসরটি ব্যবহার নিশ্চিত করুন। যে পরিসর মূল্যবোধের আউট বিপর্যস্ত করা হবে না একটি পরিসীমা সঙ্গে subscripting জন্য আপনি এই ব্যবহার করতে পারেন বাস্তবায়ন


কেন এটি অন্তর্নির্মিত নয়?

ত্রুটি বার্তাটি "আলোচনার জন্য ডকুমেন্টেশন মন্তব্যটি দেখুন" বলে । অ্যাপল অনুপলব্ধ স্ট্রিংএপিআইএস.সুইফ্ট ফাইলটিতে নিম্নলিখিত ব্যাখ্যা সরবরাহ করে :

পূর্ণসংখ্যার সাথে সাবস্ক্রিপশন স্ট্রিং উপলভ্য নয়।

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

সুইফিং স্ট্রিংয়ের অভ্যন্তরে সঞ্চিত অক্ষর ডেটা অ্যাক্সেস করার বিভিন্ন উপায় প্রদান করে।

  • String.utf8স্ট্রিংয়ের UTF-8 কোড ইউনিটের একটি সংগ্রহ is স্ট্রিংটিকে ইউটিএফ -8 এ রূপান্তর করার সময় এই API টি ব্যবহার করুন। বেশিরভাগ পসিক্স এপিআইগুলি ইউটিএফ -8 কোড ইউনিটের ক্ষেত্রে স্ট্রিং প্রক্রিয়া করে।

  • String.utf16স্ট্রিংয়ে ইউটিএফ -16 কোড ইউনিটের সংগ্রহ is বেশিরভাগ কোকো এবং কোকো টাচ এপিআইগুলি ইউটিএফ -16 কোড ইউনিটের ক্ষেত্রে স্ট্রিংগুলি প্রসেস করে। উদাহরণস্বরূপ, দৃষ্টান্ত NSRangeসঙ্গে ব্যবহার NSAttributedStringএবং NSRegularExpressionদোকান হল UTF-16 কোড ইউনিট পদ অফসেট এবং লেন্থ সাবস্ট্রিং।

  • String.unicodeScalarsএটি ইউনিকোড স্কেলারের সংগ্রহ। আপনি যখন চরিত্রের ডেটা নিম্ন স্তরের হেরফের করছেন তখন এই API টি ব্যবহার করুন API

  • String.characters হ'ল বর্ধিত গ্রাফি ক্লাস্টারগুলির সংকলন যা ব্যবহারকারী-অনুধাবিত অক্ষরের একটি অনুমান।

নোট করুন যে স্ট্রিংগুলিতে মানব-পঠনযোগ্য পাঠ্য রয়েছে এমনগুলি প্রক্রিয়া করার সময়, অক্ষর দ্বারা অক্ষর প্রক্রিয়াকরণটি সম্ভব সর্বাধিক পরিমাণে এড়ানো উচিত। উচ্চ পর্যায়ের ব্যবহার লোকেল সংবেদনশীল ইউনিকোড আলগোরিদিম পরিবর্তে, উদাহরণস্বরূপ, String.localizedStandardCompare(), String.localizedLowercaseString, String.localizedStandardRangeOfString()ইত্যাদি


4
Cannot find an overload for 'advance' that accepts an argument list of type '(String.Index, T)'... String.Indexএবং Intসামঞ্জস্যপূর্ণ নয়।

7
যদি আপনি দেখেন Cannot subscript a value of type 'String'...: এই উত্তর চেক stackoverflow.com/a/31265316/649379
SoftDesigner

24
আমি এটি ব্যবহার করার চেষ্টা করার পরে, আমি পেতে Ambiguous use of 'subscript'
jowie

18
সতর্কবার্তা! নীচের এক্সটেনশনটি মারাত্মকভাবে অক্ষম। প্রতিবার পূর্ণসংখ্যার সাহায্যে স্ট্রিং অ্যাক্সেস করা হলে তার সূচকটি এগিয়ে নেওয়ার জন্য একটি O (n) ফাংশন চালানো হয়। অন্য লিনিয়ার লুপের মধ্যে রৈখিক লুপ চালানো মানে লুপের জন্য এটি দুর্ঘটনাক্রমে O (n2) - স্ট্রিংয়ের দৈর্ঘ্য বাড়ার সাথে সাথে এই লুপটির সময়টি চৌম্বকভাবে বৃদ্ধি পায়। এটি না করে আপনি অক্ষরের স্ট্রিং সংগ্রহটি ব্যবহার করতে পারেন।
ইগ্যাসিওহাগোগ

2
fatal error: Can't form a Character from an empty String
ডেভিন বি

341

সুইফ্ট 5.2

let str = "abcdef"
str[1 ..< 3] // returns "bc"
str[5] // returns "f"
str[80] // returns ""
str.substring(fromIndex: 3) // returns "def"
str.substring(toIndex: str.length - 2) // returns "abcd"

আপনার প্রকল্পে এই স্ট্রিং এক্সটেনশনটি যুক্ত করতে হবে (এটি সম্পূর্ণরূপে পরীক্ষিত):

extension String {

    var length: Int {
        return count
    }

    subscript (i: Int) -> String {
        return self[i ..< i + 1]
    }

    func substring(fromIndex: Int) -> String {
        return self[min(fromIndex, length) ..< length]
    }

    func substring(toIndex: Int) -> String {
        return self[0 ..< max(0, toIndex)]
    }

    subscript (r: Range<Int>) -> String {
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)),
                                            upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    }
}

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

let str = "Hello, world!"
let index = str.index(str.startIndex, offsetBy: 4)
str[index] // returns Character 'o'

let endIndex = str.index(str.endIndex, offsetBy:-2)
str[index ..< endIndex] // returns String "o, worl"

String(str.suffix(from: index)) // returns String "o, world!"
String(str.prefix(upTo: index)) // returns String "Hell"

এতে পরিবর্তন range.upperBound - range.lowerBoundকরুনrange.count
লিও ডাবাস

এটি মূল প্রশ্নের অংশ নয়, তবে ... এটি সমর্থিত অ্যাসাইনমেন্টটিও ভাল লাগবে। উদাহরণস্বরূপ, এস [i] = "এ" :)।
ক্রিস প্রিন্স

2
আমি বিশ্বাস করি সুইফটের সাথে 4.2 সাবস্ক্রিপ্টগুলি আর উপলভ্য নয়। আমি এই বলে একটি ত্রুটি পেয়েছি: 'সাবস্ক্রিপ্ট' অনুপলব্ধ: স্ট্রিং কোনও
ইন্টির

2
@ ক্রিসপ্রিন্সextension StringProtocol where Self: RangeReplaceableCollection { subscript(offset: Int) -> Element { get { return self[index(startIndex, offsetBy: offset)] } set { let start = index(startIndex, offsetBy: offset) replaceSubrange(start..<index(after: start), with: [newValue]) } } }
লিও ডাবাস

এটি অন্তর্নির্মিত ফাংশনগুলি হওয়া উচিত
আম্মার মুজিব

150

আমি সবেমাত্র এই ঝরঝরে কাজটি নিয়ে এসেছি

var firstChar = Array(string)[0]

2
এটি (সাধারণ) কেস যেখানে আপনি জানেন যে আপনার কাছে ইউটিএফ 8 বা এএসসিআইআই এনকোডযুক্ত স্ট্রিং রয়েছে তার জন্য এটি দ্রুত কাজ করার একটি দুর্দান্ত কাজ। কেবলমাত্র নিশ্চিত হয়ে নিন যে স্ট্রিংগুলি এমন কোনও এনকোডিংতে থাকবে না যা একাধিক বাইট ব্যবহার করে।
জেফ হেই

47
আপনি কেবল প্রথম অক্ষর পেতে পুরো স্ট্রিংটি অনুলিপি করছেন বলে এটি অত্যন্ত অযোগ্য বলে মনে হচ্ছে। স্ট্রিং [স্ট্রিং ব্যবহার করুন। সুলতান ইশারা করে 0 এর পরিবর্তে startIndex]।
বুড়ো

6
মোড়ক খালি: var firstChar = Array(string!)[0]অন্যথায় এটি বলবেadd arrayLiteral
মোহাম্মদ যায়েদ পাঠান

2
আমি বিশ্বাস করি না যে এটি পরিষ্কার, কারণ এটি প্রায় গোলাকার। অ্যারেতে কোন ইনিশিয়ালাইজারটি প্রথমে এটি হওয়ার কারণে ব্যবহৃত হয়েছে তা আমি নিশ্চিত নই (এবং আমি ধরে নিচ্ছি যে এটি সিকোয়েন্সটাইপ ইনিশিয়ালাইজারের ফলে এটি অ্যারের জন্য পৃথক উপাদান হিসাবে স্ট্রিংয়ের অক্ষরগুলি সংগ্রহ করে)। এটি মোটেও সুস্পষ্ট নয় এবং প্রকারের ingালাই ছাড়াই ভবিষ্যতে সংশোধন করা যেতে পারে। আপনি যদি [স্ট্রিং] .প্রথমের মাধ্যমে অ্যারের জন্য শর্টহ্যান্ড ব্যবহার করেন তবে এটিও কাজ করে না। @ সুলতানের সমাধান সূচক মানগুলিতে বেকড ব্যবহার করতে সর্বোত্তম কাজ করে। এখানে কী ঘটছে তা এটি আরও বেশি স্পষ্ট।
TheCodingArt

2
বাহ, সংকলক বিভাগের দোষ!
ফ্রাঙ্ক

124

কোন ইন্ডেক্স ইন্টিজার ব্যবহার করে শুধুমাত্র ব্যবহার String.Index। বেশিরভাগ ক্ষেত্রে লিনিয়ার জটিলতা। আপনি String.Indexএগুলি ব্যবহার করে রেঞ্জগুলি তৈরি করতে এবং সাবস্ট্রিংগুলিও পেতে পারেন ।

সুইফট 3.0

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.index(before: someString.endIndex)]
let charAtIndex = someString[someString.index(someString.startIndex, offsetBy: 10)]

let range = someString.startIndex..<someString.index(someString.startIndex, offsetBy: 10)
let substring = someString[range]

সুইফট 2.x

let firstChar = someString[someString.startIndex]
let lastChar = someString[someString.endIndex.predecessor()]
let charAtIndex = someString[someString.startIndex.advanceBy(10)]

let range = someString.startIndex..<someString.startIndex.advanceBy(10)
let subtring = someString[range]

মনে রাখবেন যে আপনি কখনই এক স্ট্রিং থেকে অন্য স্ট্রিংয়ের তৈরি সূচক (বা ব্যাপ্তি) ব্যবহার করতে পারবেন না

let index10 = someString.startIndex.advanceBy(10)

//will compile
//sometimes it will work but sometimes it will crash or result in undefined behaviour
let charFromAnotherString = anotherString[index10]

7
Stringসূচিগুলি একটি স্ট্রিংয়ের জন্য অনন্য। এটি কারণ বিভিন্ন স্ট্রিংয়ের বিভিন্ন মাল্টি-ইউনিট ইউটিএফ -16 Charactersএবং / বা বিভিন্ন অবস্থানে থাকতে পারে তাই ইউটিএফ -16 ইউনিট সূচকগুলি মেলে না, শেষের বাইরে চলে যেতে পারে বা মাল্টি-ইউনিট ইউটিএফ -16 এর ভিতরে পয়েন্ট হতে পারে Character
জাফ

@ জাফ এটি সুস্পষ্ট।
সুলতান

3
আপনি কেন বলছেন তা ব্যাখ্যা করে: "কখনও কখনও এটি ক্রাশ হয়ে যায় বা সংজ্ঞায়িত আচরণের ফলস্বরূপ"। সম্ভবত এটি করা যাবেন না বলেই আরও ভাল কারণ ...
zaph

1
@ সুলতান ..এখন ..<(আপনার নিয়োগের ক্ষেত্রে range)
অ্যারন ব্র্যাজার

3
@ কেজুনলুক আমি জানি আপনি যখন এই মন্তব্যটি পোস্ট করেছেন তখন কিছুটা সময় হয়ে গেছে তবে এই উত্তরটি একবার দেখুন । আপনি ব্যবহার করতে পারেনvar lastChar = string[string.endIndex.predecessor()]
ডেভিড এল

122

এক্সকোড 11 • সুইফ্ট 5.1

সাবস্ক্রিপ্টগুলিতে সাবস্ক্রিপ্টটি উপলব্ধ করার জন্য আপনি স্ট্রিংপ্রোটোকল প্রসারিত করতে পারেন:

extension StringProtocol {
    subscript(_ offset: Int)                     -> Element     { self[index(startIndex, offsetBy: offset)] }
    subscript(_ range: Range<Int>)               -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: ClosedRange<Int>)         -> SubSequence { prefix(range.lowerBound+range.count).suffix(range.count) }
    subscript(_ range: PartialRangeThrough<Int>) -> SubSequence { prefix(range.upperBound.advanced(by: 1)) }
    subscript(_ range: PartialRangeUpTo<Int>)    -> SubSequence { prefix(range.upperBound) }
    subscript(_ range: PartialRangeFrom<Int>)    -> SubSequence { suffix(Swift.max(0, count-range.lowerBound)) }
}

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension BidirectionalCollection {
    subscript(safe offset: Int) -> Element? {
        guard !isEmpty, let i = index(startIndex, offsetBy: offset, limitedBy: index(before: endIndex)) else { return nil }
        return self[i]
    }
}

পরীক্ষামূলক

let test = "Hello USA 🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[safe: 10]   // "🇺🇸"
test[11]   // "!"
test[10...]   // "🇺🇸!!! Hello Brazil 🇧🇷!!!"
test[10..<12]   // "🇺🇸!"
test[10...12]   // "🇺🇸!!"
test[...10]   // "Hello USA 🇺🇸"
test[..<10]   // "Hello USA "
test.first   // "H"
test.last    // "!"

// Subscripting the Substring
 test[...][...3]  // "Hell"

// Note that they all return a Substring of the original String.
// To create a new String from a substring
test[10...].string  // "🇺🇸!!! Hello Brazil 🇧🇷!!!"

আমি কি জিজ্ঞাসা করতে পারি "স্ব [সূচক (স্টার্টইন্ডেক্স, অফসেটবি: আই)]" কি? এবং "স্ব [i]" কীভাবে কাজ করে?
অ্যালেনলিলি

1
হাই লিও, সমাধানের জন্য আপনাকে ধন্যবাদ! আমি সবেমাত্র (আজ) স্যুইফট ২.৩ থেকে ৩ তে স্যুইচ করেছি এবং আপনার সমাধান সাবস্ক্রিপ্ট (ব্যাপ্তি: ব্যাপ্তি <আইটি>) ত্রুটিটি দেয় "কলটিতে অতিরিক্ত যুক্তি 'লিমিটেড বাই'" দেয়। আপনার কী মনে হচ্ছে ভুল হতে পারে?
আহমেট আক্কাক

@ আহমেটআক্কাক আপনি কি কোডটি পরিবর্তন করেন নি?
লিও ডাবাস

1
@ লিয়ো এটি প্রমাণিত হয়েছে যে আমি পুরো প্রকল্পটি রূপান্তর করি নি তবে অ্যাপটিতে এক্সটেনশনটি নয়, আমি অ্যাপ্লিকেশন এবং এক্সটেনশন উভয়ের জন্যই প্রক্রিয়াটি পুনরাবৃত্তি করেছি এবং এটি এখন ঠিক আছে। আপনার সাহায্যের খুব প্রশংসা করা হয়!
আহমেট আক্কাক

এটি খুব জটিল কোড। return String(Array(characters)[range])সুইফট 3 এ করার সুবিধা কী ?
ড্যান রোজনস্টার্ক

67

সুইফট 4

let str = "My String"

স্ট্রিং এ ইনডেক্স

let index = str.index(str.startIndex, offsetBy: 3)
String(str[index])    // "S"

সাবস্ট্রিং

let startIndex = str.index(str.startIndex, offsetBy: 3)
let endIndex = str.index(str.startIndex, offsetBy: 7)
String(str[startIndex...endIndex])     // "Strin"

প্রথম এন অক্ষর

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[..<startIndex])    // "My "

শেষ এন অক্ষর

let startIndex = str.index(str.startIndex, offsetBy: 3)
String(str[startIndex...])    // "String"

সুইফট 2 এবং 3

str = "My String"

** স্ট্রিং এ ইনডেক্স **

সুইফট 2

let charAtIndex = String(str[str.startIndex.advancedBy(3)])  // charAtIndex = "S"

সুইফট 3

str[str.index(str.startIndex, offsetBy: 3)]

ইনডেক্স থেকে ইনডেক্সে সাবস্ট্রিং

সুইফট 2

let subStr = str[str.startIndex.advancedBy(3)...str.startIndex.advancedBy(7)] // subStr = "Strin"

সুইফট 3

str[str.index(str.startIndex, offsetBy: 3)...str.index(str.startIndex, offsetBy: 7)]

প্রথম এন অক্ষর

let first2Chars = String(str.characters.prefix(2)) // first2Chars = "My"

শেষ এন অক্ষর

let last3Chars = String(str.characters.suffix(3)) // last3Chars = "ing"

24

এক্সকোড 7 জিএম বীজ হিসাবে সুইফট 2.0

var text = "Hello, world!"

let firstChar = text[text.startIndex.advancedBy(0)] // "H"

নবম চরিত্রের জন্য, 0-কে n-1 দিয়ে প্রতিস্থাপন করুন।

সম্পাদনা: সুইফট 3.0

text[text.index(text.startIndex, offsetBy: 0)]


এনবি স্ট্রিংয়ে কিছু নির্দিষ্ট অক্ষর দখল করার সহজ উপায় রয়েছে

যেমন let firstChar = text.characters.first


23

আপনি যদি Cannot subscript a value of type 'String'...এই এক্সটেনশনটি ব্যবহার করতে দেখেন :

সুইফট 3

extension String {
    subscript (i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    subscript (i: Int) -> String {
        return String(self[i] as Character)
    }

    subscript (r: Range<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start..<end]
    }

    subscript (r: ClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: r.lowerBound)
        let end = index(startIndex, offsetBy: r.upperBound)
        return self[start...end]
    }
}

সুইফট 2.3

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = advance(startIndex, integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = advance(startIndex, integerRange.startIndex)
        let end = advance(startIndex, integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

সূত্র: http://oleb.net/blog/2014/07/swift-strings/


19

সুইফট ২.২ সমাধান:

নিম্নলিখিত এক্সটেনশনটি এক্সকোড 7 এ কাজ করে, এটি এই সমাধান এবং সুইফট 2.0 সিনট্যাক্স রূপান্তরটির সংমিশ্রণ ।

extension String {
    subscript(integerIndex: Int) -> Character {
        let index = startIndex.advancedBy(integerIndex)
        return self[index]
    }

    subscript(integerRange: Range<Int>) -> String {
        let start = startIndex.advancedBy(integerRange.startIndex)
        let end = startIndex.advancedBy(integerRange.endIndex)
        let range = start..<end
        return self[range]
    }
}

14

সুইট স্ট্রিং ক্লাসটি ইউটিএফ অক্ষরের জন্য স্থানীয় সমর্থন থাকার কারণে নির্দিষ্ট সূচকে একটি অক্ষর পাওয়ার ক্ষমতা সরবরাহ করে না। মেমরির কোনও ইউটিএফ চরিত্রের পরিবর্তনশীল দৈর্ঘ্য সরাসরি একটি অক্ষরে ঝাঁপিয়ে পড়া অসম্ভব করে তোলে। এর অর্থ আপনাকে প্রতিটি বারে ম্যানুয়ালি লুপ করতে হবে।

আপনি স্ট্রিংকে এমন একটি পদ্ধতি সরবরাহ করতে প্রসারিত করতে পারেন যা আপনার পছন্দসই সূচক না হওয়া পর্যন্ত অক্ষরগুলির মধ্য দিয়ে লুপ করবে

extension String {
    func characterAtIndex(index: Int) -> Character? {
        var cur = 0
        for char in self {
            if cur == index {
                return char
            }
            cur++
        }
        return nil
    }
}

myString.characterAtIndex(0)!

3
আপনি ইতিমধ্যে স্ট্রিংগুলির মধ্য দিয়ে লুপ করতে পারেন: "foo" {
প্রিন্টলনে

@Doobeh আমি মাধ্যমে লুপ বোঝানো এবং উপরোক্ত মত প্রকৃত চরিত্র আসতে আমার সম্পাদনা
drewag

চমৎকার! আপনি কীভাবে এটি পুনরুক্ত করতে পারবেন তা মজাদার তবে কোনও সূচকের মাধ্যমে নয়। সুইফ্টের অজগর অনুভূতি তবে আরও শক্ত প্রান্তের।
দোবেহ

আমি ব্যবহার করে পেয়েছি myString.bridgeToObjectiveC().characterAtIndex(0)বা (string as NSString ).characterAtIndex(0) চরিত্রটির কোনও মান মান প্রত্যাবর্তন করেছি
মার্খুন্তে

4
NSStringএকটি সুইফট-নেটিভ থেকে পৃথক অক্ষর অ্যাক্সেসের জন্য পদ্ধতি ব্যবহার করবেন নাString - দু'জন পৃথক গণনা পদ্ধতি ব্যবহার করে, তাই আপনি উচ্চতর ইউনিকোড অক্ষরগুলির সাথে অনাকাঙ্ক্ষিত ফলাফল পাবেন। প্রথম পদ্ধতিটি নিরাপদ হওয়া উচিত (একবারে সুইফ্টের ইউনিকোড বাগগুলি পরিচালনা করা হবে)।
নেট কুক

11

একটি সরল নোট হিসাবে, কয়েকটি স্ট্রিং এর চরিত্র-শৃঙ্খলার উপস্থাপনায় সরাসরি প্রয়োগযোগ্য কিছু ফাংশন রয়েছে:

var string = "Hello, playground"
let firstCharacter = string.characters.first // returns "H"
let lastCharacter = string.characters.last // returns "d"

ফলাফলটি চরিত্রের ধরণের, তবে আপনি এটি একটি স্ট্রিংয়ে কাস্ট করতে পারেন।

অথবা এটা:

let reversedString = String(string.characters.reverse())
// returns "dnuorgyalp ,olleH" 

:-)


11

সুইফট 4

String(Array(stringToIndex)[index]) 

এটি সম্ভবত এক সময় এই সমস্যা সমাধানের সেরা উপায়। আপনি সম্ভবত প্রথমে একটি অ্যারে হিসাবে স্ট্রিং কাস্ট করতে চান এবং তারপরে ফলাফলটি আবার স্ট্রিং হিসাবে ফেলে দিতে পারেন। অন্যথায়, একটি স্ট্রিংয়ের পরিবর্তে একটি অক্ষর ফিরে আসবে।

উদাহরণটি String(Array("HelloThere")[1])"e" স্ট্রিং হিসাবে ফিরে আসবে।

(Array("HelloThere")[1] অক্ষর হিসাবে "ই" প্রত্যাবর্তন করবে।

সুইফট স্ট্রিংগুলিকে অ্যারের মতো সূচীকরণের অনুমতি দেয় না, তবে এটি কাজটি করে, ব্রুট-ফোর্স শৈলী।


1
পুরো স্ট্রিংয়ের বিষয়বস্তুটিকে অন্য মেমরির স্থানে সদৃশ করা বিশেষভাবে বড় স্ট্রিংয়ের জন্য পাল্টা-পারফরম্যান্ট। ডাইরেক্ট মেমোরি অ্যাক্সেসের মতো সাধারণ কাজের জন্য আমাদের অতিরিক্ত মেমরির বরাদ্দ থাকা উচিত নয়।
ক্রিশটিক

7

আমার খুব সহজ সমাধান:

সুইফট ৪.১:

let myString = "Test string"
let index = 0
let firstCharacter = myString[String.Index(encodedOffset: index)]

সুইফ্ট 5.1:

let firstCharacter = myString[String.Index.init(utf16Offset: index, in: myString)]


সবচেয়ে সহজ সমাধান এবং এখন সুইফ্ট 5 উদাহরণ সহ :)
ওহাদএম

@ লিন দাও এনকোডডঅফসেট ব্যবহার করবেন না। এনকোডডফসেটটি অবচিত করা হয়েছে: সর্বাধিক সাধারণ ব্যবহার ভুল হওয়ায় এনকোডডফেসটি অবচিত করা হয়েছে।
লিও ডাবাস

@ ওহাদামের সহজ অর্থ এই নয় যে এটি সঠিক বা কমপক্ষে এটি আপনার প্রত্যাশার মতো কার্যকর হবে নাlet flags = "🇺🇸🇧🇷" flags[String.Index(utf16Offset: 4, in: flags)] // "🇧🇷"
লিও ডাবাস

1
@ ওহাদএম আমার মন্তব্যটি কেবল একটি সতর্কতা ছিল। আপনি যদি মনে করেন এটি এটি আপনার প্রত্যাশা মতো আচরণ করে তবে এটিকে নির্দ্বিধায় ব্যবহার করুন।
লিও ডাবাস

6

আপনি স্ট্রিংকে অ্যারেতে রূপান্তর করে এটি নীচে সাবস্ক্রিপ্ট ব্যবহার করে নির্দিষ্ট সূচক দ্বারা পেতে পারেন

var str = "Hello"
let s = Array(str)[2]
print(s)

1
নোট করুন যে এই সমাধানটির ফলে বিষয়বস্তুগুলির অনুলিপি হবে, এটি কম পারফরম্যান্ট মেমরি বুদ্ধিমান এবং সিপিইউ ভিত্তিক তৈরি করবে।
ক্রিশ্চিক

5

আমি ঠিক একই সমস্যা ছিল। কেবল এটি করুন:

var aString: String = "test"
var aChar:unichar = (aString as NSString).characterAtIndex(0)

এটি অনেক ইমোজি এবং অন্যান্য চরিত্রগুলির জন্য ব্যর্থ হয় যা আসলে একবারে "চরিত্র" এর একাধিক বার নেয় NSString
rmaddy

5

Swift3

আপনি কোনও নির্দিষ্ট স্ট্রিং সূচকে অক্ষরটি অ্যাক্সেস করতে সাবস্ক্রিপ্ট সিনট্যাক্স ব্যবহার করতে পারেন।

let greeting = "Guten Tag!"
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index] // a

পরিদর্শন https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

বা আমরা সুইফট 4 এ স্ট্রিং এক্সটেনশন করতে পারি

extension String {
    func getCharAtIndex(_ index: Int) -> Character {
        return self[self.index(self.startIndex, offsetBy: index)]
    }
}

ব্যবহার:

let foo = "ABC123"
foo.getCharAtIndex(2) //C

3

আমার সমাধানটি এক লাইনে রয়েছে, ধরুন ক্যাডেনাটি স্ট্রিং এবং 4 টি আপনি চান নবম অবস্থান:

let character = cadena[advance(cadena.startIndex, 4)]

সহজ ... আমি মনে করি সুইফট ভবিষ্যতের সংস্করণগুলিতে সাবস্ট্রিং সম্পর্কিত আরও কিছু বিষয় অন্তর্ভুক্ত করবে।


1
var charAtIndex = string[advance(string.startIndex, 10)]সুলতানের উত্তরে কি তেমনটা হয় না?
মার্টিন আর

হ্যাঁ, সুলতান যেমন বলেছিলেন তেমন একটি উদাহরণ সহ এটি একই সমাধান। সদৃশটির জন্য দুঃখিত :) এটি সহজ দুটি ব্যক্তি একইভাবে পাওয়া যায়।
জুলিও সিজার ফার্নান্দেজ

3

সুইফট 3: অন্য সমাধান (খেলার মাঠে পরীক্ষিত)

extension String {
    func substr(_ start:Int, length:Int=0) -> String? {
        guard start > -1 else {
            return nil
        }

        let count = self.characters.count - 1

        guard start <= count else {
            return nil
        }

        let startOffset = max(0, start)
        let endOffset = length > 0 ? min(count, startOffset + length - 1) : count

        return self[self.index(self.startIndex, offsetBy: startOffset)...self.index(self.startIndex, offsetBy: endOffset)]
    }
}

ব্যবহার:

let txt = "12345"

txt.substr(-1) //nil
txt.substr(0) //"12345"
txt.substr(0, length: 0) //"12345"
txt.substr(1) //"2345"
txt.substr(2) //"345"
txt.substr(3) //"45"
txt.substr(4) //"5"
txt.substr(6) //nil
txt.substr(0, length: 1) //"1"
txt.substr(1, length: 1) //"2"
txt.substr(2, length: 1) //"3"
txt.substr(3, length: 1) //"4"
txt.substr(3, length: 2) //"45"
txt.substr(3, length: 3) //"45"
txt.substr(4, length: 1) //"5"
txt.substr(4, length: 2) //"5"
txt.substr(5, length: 1) //nil
txt.substr(5, length: -1) //nil
txt.substr(-1, length: -1) //nil

2

সুইফট 2.0 সাবস্ট্রিংয়ের জন্য আপডেট

public extension String {
    public subscript (i: Int) -> String {
        return self.substringWithRange(self.startIndex..<self.startIndex.advancedBy(i + 1))
    }

    public subscript (r: Range<Int>) -> String {
        get {
            return self.substringWithRange(self.startIndex.advancedBy(r.startIndex)..<self.startIndex.advancedBy(r.endIndex))
        }
    }

}

2

আমি মনে করি যে প্রথম চরিত্রটি পাওয়ার জন্য দ্রুত উত্তরটি হতে পারে:

let firstCharacter = aString[aString.startIndex]

এটি এর চেয়ে অনেক মার্জিত এবং পারফরম্যান্স:

let firstCharacter = Array(aString.characters).first

তবে .. আপনি যদি কৌশলটি ব্যবহার করতে চান এবং স্ট্রিংগুলির সাথে আরও বেশি অপারেশন করতে চান তবে আপনি একটি এক্সটেনশন তৈরি করতে পারেন বলে মনে করতে পারেন this

extension String {
var length : Int {
    return self.characters.count
}

subscript(integerIndex: Int) -> Character {
    let index = startIndex.advancedBy(integerIndex)
    return self[index]
}

subscript(integerRange: Range<Int>) -> String {
    let start = startIndex.advancedBy(integerRange.startIndex)
    let end = startIndex.advancedBy(integerRange.endIndex)
    let range = start..<end
    return self[range]
}

}

তবে এটি একটি বিশ্বাসযোগ্য আইডিয়া !!

নীচের এক্সটেনশনটি মারাত্মকভাবে অক্ষম। প্রতিবার পূর্ণসংখ্যার সাহায্যে স্ট্রিং অ্যাক্সেস করা হলে তার সূচকটি এগিয়ে নেওয়ার জন্য একটি O (n) ফাংশন চালানো হয়। অন্য লিনিয়ার লুপের মধ্যে রৈখিক লুপ চালানো মানে লুপের জন্য এটি দুর্ঘটনাক্রমে O (n2) - স্ট্রিংয়ের দৈর্ঘ্য বাড়ার সাথে সাথে এই লুপটির সময়টি চৌম্বকভাবে বৃদ্ধি পায়।

এটি না করে আপনি অক্ষরের স্ট্রিং সংগ্রহটি ব্যবহার করতে পারেন।


2

সুইফট 3

extension String {

    public func charAt(_ i: Int) -> Character {
        return self[self.characters.index(self.startIndex, offsetBy: i)]
    }

    public subscript (i: Int) -> String {
        return String(self.charAt(i) as Character)
    }

    public subscript (r: Range<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

    public subscript (r: CountableClosedRange<Int>) -> String {
        return substring(with: self.characters.index(self.startIndex, offsetBy: r.lowerBound)..<self.characters.index(self.startIndex, offsetBy: r.upperBound))
    }

}

ব্যবহার

let str = "Hello World"
let sub = str[0...4]

সহায়ক প্রোগ্রামিং টিপস এবং কৌশল (আমার লিখিত)


2

সাবস্ক্রিপ্ট পান এবং সেট করুন (স্ট্রিং এবং সাবস্ট্রিং) - সুইফট 4.2

সুইফট 4.2, এক্সকোড 10

আমি আমার উত্তর @ আলেকার্লসনের উত্তর বন্ধ করে দিয়েছি । একমাত্র বড় পার্থক্য হ'ল আপনি একটি Substringবা Stringফেরত পেতে পারেন (এবং কিছু ক্ষেত্রে একক Character)। আপনি getএবং setসাবস্ক্রিপ্ট করতে পারেন । অবশেষে, আমার কাছে @ আলেকার্লসনের জবাবের চেয়ে কিছুটা বেশি জটিল এবং দীর্ঘতর , আমি আপনাকে এটি কোনও উত্স ফাইলে রেখে দেওয়ার পরামর্শ দিই।


এক্সটেনশান:

public extension String {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            self.replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}
public extension Substring {
    public subscript (i: Int) -> Character {
        get {
            return self[index(startIndex, offsetBy: i)]
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }

    }
    public subscript (bounds: CountableRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ..< end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> Substring {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return self[start ... end]
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: PartialRangeThrough<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ... end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> Substring {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return self[startIndex ..< end]
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }
    public subscript (i: Int) -> String {
        get {
            return "\(self[index(startIndex, offsetBy: i)])"
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
    public subscript (bounds: CountableRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ..< end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ..< end, with: s)
        }
    }
    public subscript (bounds: CountableClosedRange<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(start ... end, with: s)
        }

    }
    public subscript (bounds: CountablePartialRangeFrom<Int>) -> String {
        get {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            return "\(self[start ... end])"
        }
        set (s) {
            let start = index(startIndex, offsetBy: bounds.lowerBound)
            let end = index(endIndex, offsetBy: -1)
            replaceSubrange(start ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeThrough<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ... end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ... end, with: s)
        }
    }
    public subscript (bounds: PartialRangeUpTo<Int>) -> String {
        get {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            return "\(self[startIndex ..< end])"
        }
        set (s) {
            let end = index(startIndex, offsetBy: bounds.upperBound)
            replaceSubrange(startIndex ..< end, with: s)
        }
    }

    public subscript (i: Int) -> Substring {
        get {
            return Substring("\(self[index(startIndex, offsetBy: i)])")
        }
        set (c) {
            let n = index(startIndex, offsetBy: i)
            replaceSubrange(n...n, with: "\(c)")
        }
    }
}

এটি অপ্রয়োজনীয়ভাবে সূচিপত্র (সূচনা এবং শেষ) উভয় সূচি অফসেট করে I আপনি কেবলমাত্র পরিসীমা গণনাটি ব্যবহার করে শেষ সূচকটি অফসেট করতে এবং সূচনা সূচকে অফসেট করতে পারেন
লিও ডাবাস

2

সুইফট 4.2

এই উত্তরটি আদর্শ কারণ এটি প্রসারিত হয় Stringএবং এর সমস্ত Subsequences( Substring) এক এক্সটেনশনে

public extension StringProtocol {

    public subscript (i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }

    public subscript (bounds: CountableClosedRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start...end]
    }

    public subscript (bounds: CountableRange<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[start..<end]
    }

    public subscript (bounds: PartialRangeUpTo<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex..<end]
    }

    public subscript (bounds: PartialRangeThrough<Int>) -> SubSequence {
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return self[startIndex...end]
    }

    public subscript (bounds: CountablePartialRangeFrom<Int>) -> SubSequence {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        return self[start..<endIndex]
    }
}

ব্যবহার

var str = "Hello, playground"

print(str[5...][...5][0])
// Prints ","

এটি অপ্রয়োজনীয়ভাবে উভয় সূচক ( startএবং end) থেকে অফসেট করে startIndex। আপনি কেবল অফসেট পারে endrange.count ব্যবহার সূচক ও অফসেট startসূচক
লিও Dabus

2

এতক্ষণে সাবস্ক্রিপ্ট (_ :) অনুপলব্ধ। পাশাপাশি আমরা এটি করতে পারি না

str[0] 

স্ট্রিং সহ.আমাদের "স্ট্রিং.ইনডেক্স" সরবরাহ করতে হবে তবে আমরা কীভাবে আমাদের নিজস্ব সূচক নম্বরটি দিতে পারি, পরিবর্তে আমরা ব্যবহার করতে পারি,

string[str.index(str.startIndex, offsetBy: 0)]

আপনার উত্তরটি সম্পাদনা করুন এবং কেবল উত্তর-পোস্টের উত্তর পোস্ট করার পরিবর্তে আপনার উত্তর কীভাবে সমস্যার সমাধান করে তা ব্যাখ্যা করে কিছু প্রসঙ্গ যুক্ত করুন। পর্যালোচনা থেকে
পেড্রাম পারসিয়ান

কেন অপ্রয়োজনীয় অফসেট-ইনিং করছেন? কেন সহজভাবে নয় string[string.startIndex]? বিটিডাব্লু, কোডটি সঠিকভাবে আচরণ / সংকলন করবে না, কারণ আপনি দুটি ভিন্ন ভেরিয়েবল নাম ব্যবহার করেছেন।
ক্রিশটিক

2

4.2 বা তারপরে সুইফট করুন

Stringএর indicesসম্পত্তি ব্যবহার করে ব্যাপ্তি এবং আংশিক ব্যাপ্তি সাবস্ক্রিপশন

@ লিওডাবাসের ভিন্নতা হিসাবে উত্তরের উত্তর আমরা জন্য কাস্টম সাবস্ক্রিপ্টগুলি ( বিশেষ রেঞ্জ এবং আংশিক রেঞ্জ দ্বারা) প্রয়োগ করার সময় DefaultIndicesআমাদের indicesসম্পত্তির পিছনে ফিরে সাথে একটি অতিরিক্ত বর্ধন যোগ করতে পারি ।StringInt

extension DefaultIndices {
    subscript(at: Int) -> Elements.Index { index(startIndex, offsetBy: at) }
}

// Moving the index(_:offsetBy:) to an extension yields slightly
// briefer implementations for these String extensions.
extension String {
    subscript(range: Range<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start..<indices[start...][range.count]]
    }
    subscript(range: ClosedRange<Int>) -> SubSequence {
        let start = indices[range.lowerBound]
        return self[start...indices[start...][range.count]]
    }
    subscript(range: PartialRangeFrom<Int>) -> SubSequence {
        self[indices[range.lowerBound]...]
    }
    subscript(range: PartialRangeThrough<Int>) -> SubSequence {
        self[...indices[range.upperBound]]
    }
    subscript(range: PartialRangeUpTo<Int>) -> SubSequence {
        self[..<indices[range.upperBound]]
    }
}

let str = "foo bar baz bax"
print(str[4..<6]) // "ba"
print(str[4...6]) // "bar"
print(str[4...])  // "bar baz bax"
print(str[...6])  // "foo bar"
print(str[..<6])  // "foo ba"

ব্যবহারের দিকনির্দেশে আমাকে নির্দেশ করার জন্য @ লিওডাবাসকে ধন্যবাদ জানাই indicesStringসাবস্ক্রিপশনের বিকল্পটিকে (অন্য) বিকল্প হিসাবে !


1
একমাত্র অসুবিধা হ'ল কাউন্টেবল ক্ল্যাজডরেঞ্জ স্টার্ট ইন্ডেক্স থেকে উভয় সূচকে অফসেট করবে
লিও ডাবাস

1
পছন্দ করুন হ্যাঁ বেশিরভাগ লিনাক্স তবে আজকাল খুব বেশি সুইফট নেই: / আমি swiftenvযখন ব্যবহার করি তখনই আমি ব্যবহার করি, তবে আমার ধারণা এটি খুব শীঘ্রই 4.2 দিয়ে আপডেট হবে।
dfri

1
এই উত্তরটি আধুনিক সুইফটে আপডেট করার জন্য @ লিওডাবাসকে ধন্যবাদ!
dfri

1
@ লিওডাবাস দুর্দান্ত কাজ! পরবর্তী সময়ে বিশদটি সন্ধান করতে হবে, তবে আমি মনে করতে পারি যে আমি কখনই পছন্দ করি নি যে আমাদের অর্ডার / গণনাযোগ্য সেট ধরণের কয়েকটি ফাউন্ডেশনে ফিরে যেতে হয়েছিল।
dfri

1
ধন্যবাদ, বন্ধু!!!
লিও ডাবাস

2

সুইফ্ট 5.1.3:

একটি স্ট্রিং এক্সটেনশন যুক্ত করুন:

extension String {

 func stringAt(_ i: Int) -> String { 
   return String(Array(self)[i]) 
 } 

 func charAt(_ i: Int) -> Character { 
  return Array(self)[i] 
 } 
}

let str = "Teja Kumar"
let str1: String = str.stringAt(2)  //"j"
let str2: Character = str.charAt(5)  //"k"

1
এটি যখনই আপনি এই বৈশিষ্ট্যটি থেকে একটি একক অক্ষর আহরণের জন্য কল করবেন তখন এটি পুরো স্ট্রিংকে অক্ষরের অ্যারে রূপান্তর করবে।
লিও ডাবাস

1

সুইফট Stringটাইপ একটি সরবরাহ করে নাcharacterAtIndex পদ্ধতি সরবরাহ কারণ ইউনিকোড স্ট্রিংটি এনকোড করার বিভিন্ন উপায় রয়েছে। আপনি কি ইউটিএফ 8, ইউটিএফ 16, বা অন্য কিছু নিয়ে যাচ্ছেন?

আপনি CodeUnitসংস্থানগুলি String.utf8এবং String.utf16বৈশিষ্ট্যগুলি পুনরুদ্ধার করে অ্যাক্সেস করতে পারেন । আপনি UnicodeScalarসংগ্রহটি পুনরুদ্ধার করে অ্যাক্সেস করতে পারেনString.unicodeScalars সম্পত্তি ।

NSStringএর বাস্তবায়নের চেতনায় , আমি আবার ফিরে আসছি unichar

extension String
{
    func characterAtIndex(index:Int) -> unichar
    {
        return self.utf16[index]
    }

    // Allows us to use String[index] notation
    subscript(index:Int) -> unichar
    {
        return characterAtIndex(index)
    }
}

let text = "Hello Swift!"
let firstChar = text[0]

এটি এমন অক্ষরের জন্য ব্যর্থ হবে যেগুলির জন্য 16 বিটের চেয়ে বেশি স্টোরেজ দরকার। মূলত, ইউ + এফএফএফএফ এর বাইরে যে কোনও ইউনিকোড অক্ষর।
rmaddy

1

বিষয়টিকে খাওয়ানোর জন্য এবং দ্রুত সাবস্ক্রিপ্টের সম্ভাব্যতাগুলি দেখানোর জন্য, এখানে একটি ছোট স্ট্রিং "সাবস্ট্রিং-টুলবাক্স" সাবস্ক্রিপ্ট ভিত্তিক

এই পদ্ধতিগুলি নিরাপদ এবং স্ট্রিং সূচকগুলির উপরে কখনই যায় না

extension String {
    // string[i] -> one string char
    subscript(pos: Int) -> String { return String(Array(self)[min(self.length-1,max(0,pos))]) }

    // string[pos,len] -> substring from pos for len chars on the left
    subscript(pos: Int, len: Int) -> String { return self[pos, len, .pos_len, .left2right] }

    // string[pos, len, .right2left] -> substring from pos for len chars on the right
    subscript(pos: Int, len: Int, way: Way) -> String { return self[pos, len, .pos_len, way] }

    // string[range] -> substring form start pos on the left to end pos on the right
    subscript(range: Range<Int>) -> String { return self[range.startIndex, range.endIndex, .start_end, .left2right] }

    // string[range, .right2left] -> substring start pos on the right to end pos on the left
    subscript(range: Range<Int>, way: Way) -> String { return self[range.startIndex, range.endIndex, .start_end, way] }

    var length: Int { return countElements(self) }
    enum Mode { case pos_len, start_end }
    enum Way { case left2right, right2left }
    subscript(var val1: Int, var val2: Int, mode: Mode, way: Way) -> String {
        if mode == .start_end {
            if val1 > val2 { let val=val1 ; val1=val2 ; val2=val }
            val2 = val2-val1
        }
        if way == .left2right {
            val1 = min(self.length-1, max(0,val1))
            val2 = min(self.length-val1, max(1,val2))
        } else {
            let val1_ = val1
            val1 = min(self.length-1, max(0, self.length-val1_-val2 ))
            val2 = max(1, (self.length-1-val1_)-(val1-1) )
        }
        return self.bridgeToObjectiveC().substringWithRange(NSMakeRange(val1, val2))

        //-- Alternative code without bridge --
        //var range: Range<Int> = pos...(pos+len-1)
        //var start = advance(startIndex, range.startIndex)
        //var end = advance(startIndex, range.endIndex)
        //return self.substringWithRange(Range(start: start, end: end))
    }
}


println("0123456789"[3]) // return "3"

println("0123456789"[3,2]) // return "34"

println("0123456789"[3,2,.right2left]) // return "56"

println("0123456789"[5,10,.pos_len,.left2right]) // return "56789"

println("0123456789"[8,120,.pos_len,.right2left]) // return "01"

println("0123456789"[120,120,.pos_len,.left2right]) // return "9"

println("0123456789"[0...4]) // return "01234"

println("0123456789"[0..4]) // return "0123"

println("0123456789"[0...4,.right2left]) // return "56789"

println("0123456789"[4...0,.right2left]) // return "678" << because ??? range can wear endIndex at 0 ???

1

একটি অজগর মত সমাধান, যা আপনাকে নেতিবাচক সূচক ব্যবহার করতে দেয়,

var str = "Hello world!"
str[-1]        // "!"

হতে পারে:

extension String {
    subscript (var index:Int)->Character{
        get {
            let n = distance(self.startIndex, self.endIndex)
            index %= n
            if index < 0 { index += n }
            return self[advance(startIndex, index)]
        }
    }
}

যাইহোক, পুরো অজগরটির স্লাইস নোটেশনটি স্থানান্তর করা এটির পক্ষে উপযুক্ত


আপনি কি সুইফট 4-র জন্য সংকলিত এমন কিছু লিখতে আপত্তি করেন? শেষ রিটার্ন ... লাইন অগ্রিম কাজ করে না বলে মনে হচ্ছে () ফাংশন নেই সেখানে আমি বিশ্বাস করি।
C0D3

1

আপনি স্ট্রিংকে অক্ষরের অ্যারেতে রূপান্তর করতে পারেন:

let text = "My Text"
let index = 2
let charSequence = text.unicodeScalars.map{ Character($0) }
let char = charSequence[index]

স্থির সময়ে নির্দিষ্ট সূচীতে চারটি পাওয়ার উপায়।

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

let char = text[text.startIndex.advancedBy(index)]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.