সুইফটে, কোনও স্ট্রিংকে এনুমে রূপান্তর করা কি সম্ভব?


96

আমার সাথে যদি ক, খ, সি, ডি ক্ষেত্রে এনাম থাকে তবে এনাম হিসাবে "এ" স্ট্রিংটি দেওয়া কি আমার পক্ষে সম্ভব?


4
এই 'কাস্ট'গুলিকে আক্ষরিক রূপান্তর বলা হয়।
ভাতসাল মানট

উত্তর:


141

অবশ্যই এনামগুলির কাঁচা মূল্য থাকতে পারে। দস্তাবেজগুলি উদ্ধৃত করতে:

কাঁচা মানগুলি স্ট্রিং, অক্ষর বা কোনও পূর্ণসংখ্যা বা ভাসমান-পয়েন্ট সংখ্যা ধরণের হতে পারে

- এর উত্স: অ্যাপল ইনক। "দ্য সুইফ্ট প্রোগ্রামিং ভাষা।" আইবুকস https://itun.es/us/jEUH0.l ,

সুতরাং আপনি এই জাতীয় কোড ব্যবহার করতে পারেন:

enum StringEnum: String 
{
  case one = "one"
  case two = "two"
  case three = "three"
}

let anEnum = StringEnum(rawValue: "one")!

print("anEnum = \"\(anEnum.rawValue)\"")

দ্রষ্টব্য: প্রতিটি মামলার পরে আপনার = "এক" ইত্যাদি লেখার দরকার নেই। ডিফল্ট স্ট্রিং মানগুলি কেসের নামের সাথে একই হয় তাই কল .rawValueকরা কেবল একটি স্ট্রিং ফেরত দেয়

সম্পাদনা

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

enum StringEnum: String 
{
  case one
  case two
  case three
}

let anEnum = StringEnum.one
print("anEnum = \"\(anEnum)\"")

দেয়

anEnum = "এক"

তবে আপনি যদি case one"মান এক" প্রদর্শন করতে চান তবে আপনার স্ট্রিংয়ের মান প্রদান করতে হবে:

enum StringEnum: String 
{
  case one   = "value one"
  case two   = "value two"
  case three = "value three"
}

কাঁচা মান অবশ্যই আক্ষরিক রূপান্তরিত হতে হবে। আপনি কেবল কোনও Hashableধরণের ব্যবহার করতে পারবেন না ।
ভাতসাল মানট

4
ঠিক আছে ... আমি অ্যাপল ডক্সকে উদ্ধৃত করেছি, যা এনাম কাঁচা মান হিসাবে ব্যবহার করা যেতে পারে এমন মানগুলির তালিকাবদ্ধ করে। স্ট্রিংস, ওপির প্রশ্ন, অন্যতম সমর্থিত প্রকার।
ডানকান সি

4
হুম, ভাবুন case one = "uno"। এখন, "one"এনুমুর মানটি কীভাবে পার্স করবেন? (স্থানীয়করণের জন্য
রবগুলি

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

4
= "one"প্রতিটি মামলার পরে আপনার লেখার দরকার নেই । ডিফল্ট স্ট্রিং মানগুলি কেসের নামের সাথে একই।
Emlai

38

তোমার যা দরকার তা হল:

enum Foo: String {
   case a, b, c, d
}

let a = Foo(rawValue: "a")
assert(a == Foo.a)

let 💩 = Foo(rawValue: "💩")
assert(💩 == nil)

এটি প্রযুক্তিগতভাবে সঠিক উত্তর নয় কারণ এটি কাঁচা মানটি পরীক্ষা করে। প্রদত্ত হিসাবে এখানে উদাহরণে, কোনও কাঁচা মান নির্দিষ্ট করা হয়নি, সুতরাং এটি স্পষ্টভাবে কেসের নামের সাথে মিলেছে, তবে যদি আপনার কাঁচা মান সহ একটি এনাম থাকে তবে এটি ব্রেক হয়ে যায়।
মার্ক এ। ডোনোহো

30

সুইফট ৪.২-এ, কেসটেটেবল প্রোটোকলটি কাঁচাভ্যালুগুলি সহ একটি এনামের জন্য ব্যবহার করা যেতে পারে, তবে স্ট্রিংটি এনাম কেস লেবেলের সাথে মেলে:

enum MyCode : String, CaseIterable {

    case one   = "uno"
    case two   = "dos"
    case three = "tres"

    static func withLabel(_ label: String) -> MyCode? {
        return self.allCases.first{ "\($0)" == label }
    }
}

ব্যবহার:

print(MyCode.withLabel("one")) // Optional(MyCode.one)
print(MyCode(rawValue: "uno"))  // Optional(MyCode.one)

4
এটি একটি দুর্দান্ত উত্তর! এটি আসলে প্রশ্নের সমাধান করে।
ম্যাট রান্ডেল

4
এটিই কেবলমাত্র উত্তর যা ওপি জিজ্ঞাসা করায় বাস্তবে কাজ করে, যা মামলার নামগুলি কাঁচা মূল্যবোধ নয়। ভাল উত্তর!
মার্ক এ। ডোনোহো

4
এটি কাজ করার সময় এটি করা খুব নিরীহ বিষয়। কোডে কেসগুলির নামগুলির ভিত্তিতে বেস কার্যকারিতা ডান না।
সুলতান

7
তার আর কী করার কথা? যদি সে কোনও ডাটাবেজে এনাম লিখতে থাকে এবং তারপরে এটি আবার ফেলে দিতে হয়?
জো

16

ইন্টার টাইপ সহ কোনও এনামের ক্ষেত্রে আপনি এটি করতে পারেন:

enum MenuItem: Int {
    case One = 0, Two, Three, Four, Five //... as much as needs

    static func enumFromString(string:String) -> MenuItem? {
        var i = 0
        while let item = MenuItem(rawValue: i) {
            if String(item) == string { return item }
            i += 1
        }
        return nil
    }
}

আর ব্যবহার করুন:

let string = "Two"
if let item = MenuItem.enumFromString(string) {
    //in this case item = 1 
    //your code
} 

4
এটি পাগল যে আপনি ভাষাতে অন্তর্নির্মিত অনুরূপ কার্যকারিতাটি ব্যবহার করতে পারবেন না। আমি কল্পনা করতে পারি আপনি উদাহরণস্বরূপ এনএস নামে JSON এ মান সংরক্ষণ করেন এবং তারপরে পার্সিংয়ের পরে এগুলিকে আবার রূপান্তর করতে হবে। enumFromStringআপনার ব্যবহৃত প্রতিটি এনামের জন্য একটি পদ্ধতি লেখা ক্রেজি মনে হচ্ছে।
পিটারডকে

4
@ পিটারডেক, দয়া করে সর্বোত্তম সম্ভাব্য বিকল্প প্রস্তাব করুন। আইগর সলিউশন আসলে আমার জন্য কাজ করেছে।
হেমং

@ হেমং এটি ঠিক আছে, ঠিক আছে, তবে এটির জন্য স্বয়ংক্রিয়ভাবে এটির জন্য আরও ভাল সমাধান হ'ল সুইফট সমর্থন। প্রতিটি এনামের জন্য ম্যানুয়ালি এটি করা পাগল। তবে হ্যাঁ, এটি কাজ করে।
পিটারডকে

@ পিটারডকে, আপনি কি দয়া করে এর জন্য আলাদা উত্তর যুক্ত করতে পারেন? এটি অবশ্যই এখানে সবাইকে সাহায্য করবে।
হেমং

4
এটি পাগল নয় যে সুইফট এটিকে স্থানীয়ভাবে সমর্থন করে না। উন্মাদ বিষয়টি হ'ল কার্যকারিতা কোনও প্রকারের নামের উপর নির্ভর করে। যখন মান পরিবর্তন হয়, আপনাকে সমস্ত ব্যবহারের পুনরায় চুলক এবং নামকরণ করতে হবে। এটি সমাধানের এটি সঠিক উপায় নয়।
সুলতান

2

ডানকান সি এর উত্তর প্রসারিত করা

extension StringEnum: StringLiteralConvertible {

    init(stringLiteral value: String){
        self.init(rawValue: value)!
    }

    init(extendedGraphemeClusterLiteral value: String) {
        self.init(stringLiteral: value)
    }

    init(unicodeScalarLiteral value: String) {
        self.init(stringLiteral: value)
    }
}

2

সুইফট 4.2:

public enum PaymentPlatform: String, CaseIterable {
    case visa = "Visa card"
    case masterCard = "Master card"
    case cod = "Cod"

    var nameEnum: String {
        return Mirror(reflecting: self).children.first?.label ?? String(describing: self)
    }

    func byName(name: String) -> PaymentPlatform {
        return PaymentPlatform.allCases.first(where: {$0.nameEnum.elementsEqual(name)}) ?? .cod
    }
}

2

ইন্ট এনাম এবং তাদের স্ট্রিং প্রতিনিধিত্বের জন্য, আমি নীচে এনাম ঘোষণা করি:

enum OrderState: Int16, CustomStringConvertible {

    case waiting = 1
    case inKitchen = 2
    case ready = 3

    var description: String {
        switch self {
        case .waiting:
            return "Waiting"
        case .inKitchen:
            return "InKitchen"
        case .ready:
            return "Ready"
        }
    }

    static func initialize(stringValue: String)-> OrderState? {
        switch stringValue {
        case OrderState.waiting.description:
            return OrderState.waiting
        case OrderState.inKitchen.description:
            return OrderState.inKitchen
        case OrderState.ready.description:
            return OrderState.ready

        default:
            return nil
        }
    }
}

ব্যবহার:

order.orderState = OrderState.waiting.rawValue

let orderState = OrderState.init(rawValue: order.orderState)
let orderStateStr = orderState?.description ?? ""
print("orderStateStr = \(orderStateStr)")

0

উচ্চতর জেনারেলাইজড সলিউশন তৈরি করতে djruss70 এর উত্তরে রিফিং:

extension CaseIterable {
    static func from(string: String) -> Self? {
        return Self.allCases.first { string == "\($0)" }
    }
    func toString() -> String { "\(self)" }
}

ব্যবহার:

enum Chassis: CaseIterable {
    case pieridae, oovidae
}

let chassis: Chassis = Chassis.from(string: "oovidae")!
let string: String = chassis.toString()

দ্রষ্টব্য: এনাম @objc ঘোষণা করা থাকলে দুর্ভাগ্যক্রমে এটি কাজ করবে না। আমি যতদূর জানি সুইফট 5.3 হিসাবে জেনেছি ফোর্ব ফোর্স সলিউশন (একটি স্যুইচ স্টেটমেন্ট) ব্যতীত @objc এনাম এর সাথে কাজ করার কোনও উপায় নেই।

যদি কেউ @objc enums এর জন্য এই কাজটি করার কোনও উপায় সম্পর্কে জানতে পারে তবে আমি উত্তরে আগ্রহী হব।

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