কীভাবে "ইনডেক্স" সুইফটে "ইন্ট" টাইপ করতে হবে?


91

আমি একটি স্ট্রিংয়ের মধ্যে থাকা একটি অক্ষরের সূচককে একটি পূর্ণসংখ্যার মানতে রূপান্তর করতে চাই। শিরোলেখ ফাইলগুলি পড়ার চেষ্টা করা হয়েছিল তবে আমি প্রকারটি (উদাহরণস্বরূপ ) এর সাথে Indexপ্রোটোকলের ForwardIndexTypeসাথে খাপ খায় বলে মনে হচ্ছে তবে এর ধরণটি আমি খুঁজে পাই না distanceTo

var letters = "abcdefg"
let index = letters.characters.indexOf("c")!

// ERROR: Cannot invoke initializer for type 'Int' with an argument list of type '(String.CharacterView.Index)'
let intValue = Int(index)  // I want the integer value of the index (e.g. 2)

কোন সাহায্য প্রশংসা করা হয়।


আপনার কি এক্সকোড 7.2 এবং দ্রুত 2.x আছে?
আইসাটায়েভ

আসলে, আমি এই মুহুর্তে এখনই Xcode 7.2 ডাউনলোড করছি।
ক্রিস্টোফার

33
খেলার মাঠের মুখে আপনি যে সূচকটি আপনাকে দেখতে চান তা দেখার চেয়ে হতাশার আর কিছু নেই এবং সূচিকে আপনার প্রয়োজনীয় ধরণের রূপান্তর করা এটি একটি বিশাল পিটা। আমি বরং আমার দরজায় ঠোঁট মারতাম।
অ্যাড্রিয়ান

4
সুইফ্ট 3: let index = letters.characters.index(of: "c") পরবর্তী লাইনlet int_index = letters.characters.distance(from: letters.startIndex, to: index)
ভিক্টর

8
অ্যাপল ডাব্লুটিএফ !!!!!!
বোরজ

উত্তর:


87

সম্পাদনা / আপডেট:

এক্সকোড 11 • 5.1 বা তার পরে সুইফ্ট

extension StringProtocol {
    func distance(of element: Element) -> Int? { firstIndex(of: element)?.distance(in: self) }
    func distance<S: StringProtocol>(of string: S) -> Int? { range(of: string)?.lowerBound.distance(in: self) }
}

extension Collection {
    func distance(to index: Index) -> Int { distance(from: startIndex, to: index) }
}

extension String.Index {
    func distance<S: StringProtocol>(in string: S) -> Int { string.distance(to: self) }
}

খেলার মাঠ পরীক্ষা

let letters = "abcdefg"

let char: Character = "c"
if let distance = letters.distance(of: char) {
    print("character \(char) was found at position #\(distance)")   // "character c was found at position #2\n"
} else {
    print("character \(char) was not found")
}

let string = "cde"
if let distance = letters.distance(of: string) {
    print("string \(string) was found at position #\(distance)")   // "string cde was found at position #2\n"
} else {
    print("string \(string) was not found")
}

48
আমি এত বিভ্রান্ত হয়েছি কেন তারা কেবল এমন কোনও ফাংশন করার সিদ্ধান্ত নেবে না যা কোনও অ্যারের উপাদানটির পূর্ণসংখ্যার মান সূচক ফেরত দেয় ...
smh

6
সমস্ত অক্ষর একক বাইটে সংরক্ষণ করা যায় না। আপনার কিছুটা সময় নেওয়া উচিত এবং সুইফ্ট
স্ট্রিংয়ের


4
টিবিএইচ আমি স্ট্রিং নয়, নিয়মিত অ্যারের উপাদানটির পূর্ণসংখ্যার মান সূচক পাওয়ার চেষ্টা করছি।
মার্কস কোড

28
অযথা
অসাধারণ

4

সুইফট 4

var str = "abcdefg"
let index = str.index(of: "c")?.encodedOffset // Result: 2

দ্রষ্টব্য: যদি স্ট্রিংয়ে একই একাধিক অক্ষর থাকে তবে এটি বাম থেকে নিকটস্থ একটিটি পাবে

var str = "abcdefgc"
let index = str.index(of: "c")?.encodedOffset // Result: 2

6
এনকোডড অফসেট ব্যবহার করবেন না। এনকোডডফসেটটিকে অবহেলা করা হয়েছে: সর্বাধিক সাধারণ ব্যবহার ভুল হওয়ায় এনকোডডফেসটি হ্রাস করা হয়েছে। চেষ্টা করুন"🇺🇸🇺🇸🇧🇷".index(of: "🇧🇷")?.encodedOffset // 16
লিও ডাবাস

@ লিওডাবাস আপনি সঠিকভাবে উল্লেখ করছেন যে এটি হ্রাস করা হয়েছে। তবে আপনি যাইহোক উত্তর হিসাবে এটি ব্যবহার করার পরামর্শ দিচ্ছেন। সঠিক উত্তরটি হ'ল: index_Of_YourStringVariable.utf16Offset (in: yourStringVariable)
টিডিজাইন

না। ইউটিএফ 16 এটি অফসেটটি সম্ভবত আপনি যা চান তা নয়
লিও ডাবাস

1

encodedOffsetসুইফট ৪.২ থেকে অবহেলিত হয়েছে ।

অবহেলা বার্তা: বহুল প্রচলিত ব্যবহার ভুল হওয়ায় অবচয় encodedOffsetকরা হয়েছে। ব্যবহার করুন utf16Offset(in:)একই আচরণ অর্জন করা।

সুতরাং আমরা এটির utf16Offset(in:)মতো ব্যবহার করতে পারি :

var str = "abcdefgc"
let index = str.index(of: "c")?.utf16Offset(in: str) // Result: 2

4
চেষ্টা let str = "🇺🇸🇺🇸🇧🇷" let index = str.firstIndex(of: "🇧🇷")?.utf16Offset(in: str)8: // ফল
লিও Dabus

0

সূচকের উপর ভিত্তি করে স্ট্রিং অপারেশন করতে আপনি traditionalতিহ্যবাহী সূচকের সংখ্যাসূচক পদ্ধতির সাহায্যে এটি করতে পারবেন না। কারণ swift.index সূচক ফাংশন দ্বারা পুনরুদ্ধার করা হয় এবং এটি কোন প্রকারভেদে নয়। স্ট্রিং অক্ষরগুলির একটি অ্যারে হলেও, তবুও আমরা সূচি অনুসারে উপাদানটি পড়তে পারি না।

এটি হতাশাব্যঞ্জক।

সুতরাং, স্ট্রিংয়ের প্রতিটি সমান চরিত্রের নতুন নতুন স্ট্রিং তৈরি করতে কোডের নীচে চেক করুন।

let mystr = "abcdefghijklmnopqrstuvwxyz"
let mystrArray = Array(mystr)
let strLength = mystrArray.count
var resultStrArray : [Character] = []
var i = 0
while i < strLength {
    if i % 2 == 0 {
        resultStrArray.append(mystrArray[i])
      }
    i += 1
}
let resultString = String(resultStrArray)
print(resultString)

আউটপুট: acegikmoqsuwy

আগাম ধন্যবাদ


এটি ফিল্টার দিয়ে সহজেই সম্পন্ন করা যায়var counter = 0 let result = mystr.filter { _ in defer { counter += 1 } return counter.isMultiple(of: 2) }
লিও ডাবাস

আপনি যদি স্ট্রিং.ইনডেক্সvar index = mystr.startIndex let result = mystr.filter { _ in defer { mystr.formIndex(after: &index) } return mystr.distance(from: mystr.startIndex, to: index).isMultiple(of: 2) }
লিও ডাবাস

0

এখানে একটি এক্সটেনশান যা আপনাকে মানগুলির Intপরিবর্তে একটি স্ট্রিংয়ের সীমানায় প্রবেশ করতে দেয় String.Index:

import Foundation

/// This extension is available at
/// https://gist.github.com/zackdotcomputer/9d83f4d48af7127cd0bea427b4d6d61b
extension StringProtocol {
    /// Access the range of the search string as integer indices
    /// in the rendered string.
    /// - NOTE: This is "unsafe" because it may not return what you expect if
    ///     your string contains single symbols formed from multiple scalars.
    /// - Returns: A `CountableRange<Int>` that will align with the Swift String.Index
    ///     from the result of the standard function range(of:).
    func countableRange<SearchType: StringProtocol>(
        of search: SearchType,
        options: String.CompareOptions = [],
        range: Range<String.Index>? = nil,
        locale: Locale? = nil
    ) -> CountableRange<Int>? {
        guard let trueRange = self.range(of: search, options: options, range: range, locale: locale) else {
            return nil
        }

        let intStart = self.distance(from: startIndex, to: trueRange.lowerBound)
        let intEnd = self.distance(from: trueRange.lowerBound, to: trueRange.upperBound) + intStart

        return Range(uncheckedBounds: (lower: intStart, upper: intEnd))
    }
}

কেবল সচেতন হন যে এটি অদ্ভুততার দিকে পরিচালিত করতে পারে, এজন্য অ্যাপল এটিকে কঠোর করতে বেছে নিয়েছে। (যদিও এটি একটি বিতর্কিত ডিজাইনের সিদ্ধান্ত - একটি বিপজ্জনক জিনিসটিকে কেবল শক্ত করে লুকিয়ে রাখার ...)

আপনি অ্যাপলের স্ট্রিং ডকুমেন্টেশনে আরও পড়তে পারেন , তবে tldr হ'ল এই "সূচকগুলি" আসলে বাস্তবায়ন-নির্দিষ্ট। ওএস দ্বারা রেন্ডার হওয়ার পরে তারা সূচকগুলিকে স্ট্রিংয়ে উপস্থাপন করে এবং ইউনিকোড স্পেকের কোন সংস্করণ ব্যবহৃত হচ্ছে তার উপর নির্ভর করে ওএস-ও-ওএস-এ পরিবর্তিত হতে পারে। এর অর্থ সূচক দ্বারা মানগুলি অ্যাক্সেস করা আর ধ্রুবক-সময় ক্রিয়াকলাপ নয়, কারণ স্ট্রিংয়ের সঠিক স্থান নির্ধারণের জন্য ইউটিএফ স্পেকটিকে ডেটা দিয়ে চালানো উচিত। এই সূচকগুলি এনএসএসটিং দ্বারা উত্পাদিত মানগুলির সাথেও সীমাবদ্ধ থাকবে না, যদি আপনি এটি ব্রিজ করেন, বা অন্তর্নিহিত ইউটিএফ স্কেলারগুলিতে সূচকগুলি সহ। গুহাত বিকাশকারী।


আবার সূচনাপরিবর্তনের সূত্রটি দূরত্ব পরিমাপ করার দরকার নেই। কেবল নীচ থেকে উপরের দূরত্বটি পান এবং শুরুটি যুক্ত করুন।
লিও ডাবাস

আমি আপনার পদ্ধতিতে বিকল্পগুলি যোগ করতে চাই। এর মতো কিছুfunc rangeInt<S: StringProtocol>(of aString: S, options: String.CompareOptions = []) -> Range<Int>? { guard let range = range(of: aString, options: options) else { return nil } let start = distance(from: startIndex, to: range.lowerBound) return start..<start+distance(from: range.lowerBound, to: range.upperBound) }
লিও ডাবাস

আমি সম্ভবত পদ্ধতির নামটি পরিবর্তন করে countableRangeফিরে CountableRange
যাব

পুরো বোর্ড জুড়ে @LooDabus ভাল পরামর্শ। আমি আসলে সমস্ত পরিসীমা (এর ...) টি যুক্তি যুক্ত করেছি, সুতরাং এখন আপনি গণ্যযোগ্য রেঞ্জ (এর: বিকল্পসমূহ:, পরিসর:, লোকেল :) কল করতে পারেন। গিস্ট আপডেট করেছেন, এই পোস্টটিও আপডেট করবেন।
জ্যাক

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