অ্যারে হিসাবে সমস্ত এনাম মানগুলি কীভাবে পাবেন


104

আমি নিম্নলিখিত এনাম আছে।

enum EstimateItemStatus: Printable {
    case Pending
    case OnHold
    case Done

    var description: String {
        switch self {
        case .Pending: return "Pending"
        case .OnHold: return "On Hold"
        case .Done: return "Done"
        }
    }

    init?(id : Int) {
        switch id {
        case 1:
            self = .Pending
        case 2:
            self = .OnHold
        case 3:
            self = .Done
        default:
            return nil
        }
    }
}

আমার সমস্ত কাঁচা মানগুলি স্ট্রিংগুলির অ্যারে হিসাবে পাওয়া উচিত (এর মতো ["Pending", "On Hold", "Done"])।

আমি এনামগুলিতে এই পদ্ধতিটি যুক্ত করেছি।

func toArray() -> [String] {
    var n = 1
    return Array(
        GeneratorOf<EstimateItemStatus> {
            return EstimateItemStatus(id: n++)!.description
        }
    )
}

তবে আমি নিম্নলিখিত ত্রুটি পাচ্ছি।

'জেনারেটর অফ' টাইপের জন্য কোনও প্রাথমিককরণ খুঁজে পাওয়া যায় না যা '(() -> _)' টাইপের একটি আর্গুমেন্ট তালিকা গ্রহণ করে

এটি করার কি আরও সহজ, আরও ভাল বা আরও মার্জিত উপায় আছে?


4
লেট অ্যারের মতো আপনি অ্যারে তৈরি করতে পারেন: [EstimateItemStatus] = [। অর্থ প্রদান, .হোল্ড, ডোন]
ক্রিস্তিজান ডেলিভুক

4
@ ক্রিস্টিজান দেলিভুক আমি এনামের সাথে এই কার্যকারিতা যুক্ত করতে চাই। সুতরাং আমি যেতে এবং কোডবেসের অন্যান্য জায়গাগুলিতে এটি যে কোনও জায়গায় যুক্ত করতে হবে না যদি আমি কখনও এনামে অন্য কোনও মান যুক্ত করি।
ইসুরু


আমি কোন উত্তর পাঠাতে পারেন এখানে আছে stackoverflow.com/a/48960126/5372480
MSimic

উত্তর:


156

সুইফট 4.2 (এক্সকোড 10) এবং তারপরে

একটি CaseIterableপ্রোটোকল রয়েছে:

enum EstimateItemStatus: String, CaseIterable {
    case pending = "Pending"
    case onHold = "OnHold"
    case done = "Done"

    init?(id : Int) {
        switch id {
        case 1: self = .pending
        case 2: self = .onHold
        case 3: self = .done
        default: return nil
        }
    }
}

for value in EstimateItemStatus.allCases {
    print(value)
}

সুইফ্টের জন্য <4.2

না, enumকী কী মান রয়েছে তার জন্য আপনি কোনও জিজ্ঞাসা করতে পারবেন না । এই নিবন্ধটি দেখুন । আপনাকে এমন একটি অ্যারে সংজ্ঞায়িত করতে হবে যা আপনার কাছে থাকা সমস্ত মানকে তালিকাবদ্ধ করে। " অ্যারে হিসাবে সমস্ত এনাম মানগুলি কীভাবে পাবেন " তে ফ্র্যাঙ্ক ভালবুয়েনার সমাধানটিও দেখুন ।

enum EstimateItemStatus: String {
    case Pending = "Pending"
    case OnHold = "OnHold"
    case Done = "Done"

    static let allValues = [Pending, OnHold, Done]

    init?(id : Int) {
        switch id {
        case 1:
            self = .Pending
        case 2:
            self = .OnHold
        case 3:
            self = .Done
        default:
            return nil
        }
    }
}

for value in EstimateItemStatus.allValues {
    print(value)
}

এই উত্তরটি দেখুন: সুইফট 3 কোড সহ স্ট্যাকওভারফ্লো.com / a / 28341290 / 8047
ড্যান রোজনস্টার্ক

4
AllValues ​​অংশের জন্য উত্সাহ দেওয়া, তবে এনাম স্ট্রিং টাইপ হচ্ছে তবে ইন্টের সাহায্যে আরম্ভ করা হবে তা নিশ্চিত নয়।
টাইয়ার

প্রথম লিঙ্কটি ভাঙ্গা হয়েছে তবে এখন ব্যতিক্রম ub
টিন ম্যান

40

সুইফট 4.2 নামের একটি নতুন প্রোটোকল উপস্থাপন করেছেCaseIterable

enum Fruit : CaseIterable {
    case apple , apricot , orange, lemon
}

আপনি যখন মানেন তখন আপনি enumএই জাতীয় কেসগুলি থেকে অ্যারে পেতে পারেন

for fruit in Fruit.allCases {
    print("I like eating \(fruit).")
}


17

কমপাইল সময়ে কমপক্ষে নিরাপদ থাকার অন্য উপায় রয়েছে:

enum MyEnum {
    case case1
    case case2
    case case3
}

extension MyEnum {
    static var allValues: [MyEnum] {
        var allValues: [MyEnum] = []
        switch (MyEnum.case1) {
        case .case1: allValues.append(.case1); fallthrough
        case .case2: allValues.append(.case2); fallthrough
        case .case3: allValues.append(.case3)
        }
        return allValues
    }
}

খেয়াল করুন যে এটি কোনও এনাম টাইপের (RawRepmittedable বা না) জন্য কাজ করে এবং আপনি যদি একটি নতুন কেস যুক্ত করেন তবে আপনি একটি সংকলক ত্রুটি পাবেন যা ভাল কারণ এটি আপনাকে আপ টু ডেট করতে বাধ্য করবে।


4
অপ্রচলিত, তবে এটি কার্যকর হয় এবং যদি আপনি এনামের ক্ষেত্রে পরিবর্তন করেন তবে এটি আপনাকে সতর্ক করে। চতুর সমাধান!
চক ক্রুটসিংগার

12

আমি কোথাও এই কোডটি পেয়েছি:

protocol EnumCollection : Hashable {}


extension EnumCollection {

    static func cases() -> AnySequence<Self> {
        typealias S = Self
        return AnySequence { () -> AnyIterator<S> in
            var raw = 0
            return AnyIterator {
                let current : Self = withUnsafePointer(to: &raw) { $0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee }
                }
                guard current.hashValue == raw else { return nil }
                raw += 1
                return current
            }
        }
    }
}

ব্যবহার:

enum YourEnum: EnumCollection { //code }

YourEnum.cases()

আপনারEnum থেকে মামলার তালিকা ফেরত দিন


দুর্দান্ত সমাধানের মতো বলে মনে হচ্ছে তবে সুইফট ৪
ইসুরুরু

4
"কোথাও" হতে পারে: theswiftdev.com/2017/10/12/swift-enum-all-values (অন্যদের মধ্যে?)। ব্লগার কোরকেটকে কৃতিত্ব দেয়
অমিতাইবি

4
এক্সকোড 10 এ (সুইফ্ট-সংস্করণ নির্বিশেষে) একটি এনামের হ্যাশভ্যালু হিসাবে ক্রমবর্ধমান নয় তবে এলোমেলোভাবে প্রক্রিয়া ভঙ্গ করে। এটি করার নতুন উপায় হ'ল সুইফট ৪.২ এ আপগ্রেড করা এবং কেস আইটেয়ারেবল ব্যবহার করা
ইয়াস্পার

10
enum EstimateItemStatus: String, CaseIterable {
  case pending = "Pending"
  case onHold = "OnHold"
  case done = "Done"

  static var statusList: [String] {
    return EstimateItemStatus.allCases.map { $0.rawValue }
  }
}

["মুলতুবি", "অনহোল্ড", "সম্পন্ন"]


8

ক্রিয়ামূলক উদ্দেশ্যে একটি তালিকা পেতে, এক্সপ্রেশনটি ব্যবহার করুন EnumName.allCasesযা কোনও অ্যারের উদাহরণ দেয়

EnumName.allCases.map{$0.rawValue} 

আপনাকে দেওয়া স্ট্রিংগুলির একটি তালিকা আপনাকে দেবে EnumName: String, CaseIterable

দ্রষ্টব্য: allCasesপরিবর্তে ব্যবহার করুন AllCases()


2

সুইফট 5 এর জন্য আপডেট

আমি খুঁজে পেয়েছি সবচেয়ে সহজ সমাধান হ'ল .allCasesএকটি এনাম ব্যবহার করা যা প্রসারিত হয়CaseIterable

enum EstimateItemStatus: CaseIterable {
    case Pending
    case OnHold
    case Done

    var description: String {
        switch self {
        case .Pending: return "Pending"
        case .OnHold: return "On Hold"
        case .Done: return "Done"
        }
    }

    init?(id : Int) {
        switch id {
        case 1:
            self = .Pending
        case 2:
            self = .OnHold
        case 3:
            self = .Done
        default:
            return nil
        }
    }
}

.allCasesযে কোনও CaseIterableএনামে Collectionসেই উপাদানটির একটি প্রদান করবে ।

var myEnumArray = EstimateItemStatus.allCases

কেসআইটেয়ারেবল সম্পর্কে আরও তথ্য


বিবরণ () প্রয়োগ করার দরকার নেই। প্রতিটি ক্ষেত্রে কেবল স্ট্রিংয়ের সাথে সমান করুন case OnHold = "On Hold"এবং এটি প্রতিটিটির জন্য কাঁচা মান হয়ে যায়।
pnizzle

@pnizzle আমি জানি, এটি সেখানে কারণ এটি মূল প্রশ্নে ছিল।
ক্রিস্টোফার লারসেন

1

সুইফট 2 এর জন্য

// Found http://stackoverflow.com/questions/24007461/how-to-enumerate-an-enum-with-string-type
func iterateEnum<T where T: Hashable, T: RawRepresentable>(_: T.Type) -> AnyGenerator<T> {
    var i = 0
    return AnyGenerator {
        let next = withUnsafePointer(&i) {
            UnsafePointer<T>($0).memory
        }
        if next.hashValue == i {
            i += 1
            return next
        } else {
            return nil
        }
    }
}

func arrayEnum<T where T: Hashable, T: RawRepresentable>(type: T.Type) -> [T]{
    return Array(iterateEnum(type))
}

এটি ব্যবহার করতে:

arrayEnum(MyEnumClass.self)

কেন উপাদান hashValueহবে 0..n?
এনআরিত

1

সিকোয়েন্স থেকে অনুপ্রেরণা এবং কয়েক ঘন্টা চেষ্টা করার পরে ত্রুটি। শেষ পর্যন্ত আমি এক্সকোড 9.1 এ এই আরামদায়ক এবং সুন্দর সুইফট 4 টি পথ পেয়েছি:

protocol EnumSequenceElement: Strideable {
    var rawValue: Int { get }
    init?(rawValue: Int)
}

extension EnumSequenceElement {
    func distance(to other: Self) -> Int {
        return other.rawValue - rawValue
    }

    func advanced(by n: Int) -> Self {
        return Self(rawValue: n + rawValue) ?? self
    }
}

struct EnumSequence<T: EnumSequenceElement>: Sequence, IteratorProtocol {
    typealias Element = T

    var current: Element? = T.init(rawValue: 0)

    mutating func next() -> Element? {
        defer {
            if let current = current {
                self.current = T.init(rawValue: current.rawValue + 1)
            }
        }
        return current
    }
}

ব্যবহার:

enum EstimateItemStatus: Int, EnumSequenceElement, CustomStringConvertible {
    case Pending
    case OnHold
    case Done

    var description: String {
        switch self {
        case .Pending:
            return "Pending"
        case .OnHold:
            return "On Hold"
        case .Done:
            return "Done"
        }
    }
}

for status in EnumSequence<EstimateItemStatus>() {
    print(status)
}
// Or by countable range iteration
for status: EstimateItemStatus in .Pending ... .Done {
    print(status)
}

আউটপুট:

Pending
On Hold
Done

1

তুমি ব্যবহার করতে পার

enum Status: Int{
    case a
    case b
    case c

}

extension RawRepresentable where Self.RawValue == Int {

    static var values: [Self] {
        var values: [Self] = []
        var index = 1
        while let element = self.init(rawValue: index) {
            values.append(element)
            index += 1
        }
        return values
    }
}


Status.values.forEach { (st) in
    print(st)
}

সুন্দর! সুইফট ৩.২ থেকে ৪.১ এ আপগ্রেড করার পরে এটি আমার ব্যবহার করা একটি সমাধান ছিল। আমাদের কাছে মূলত ইনিআইটারর << নিজের> ঘোষণা ছিল। আপনার সমাধানটি অনেক পরিষ্কার এবং পড়া সহজ ছিল। ধন্যবাদ!
নিক এন

4
যদিও এখানে একটি কোড ত্রুটি। এটি ক্ষেত্রে প্রথম আইটেমটি মিস করে। Var সূচক = 1 থেকে ভার সূচক = 0
নিক এন

0

যদি আপনার এনামটি ক্রমবর্ধমান হয় এবং সংখ্যার সাথে যুক্ত হয় তবে আপনি মানগুলি মানচিত্রের জন্য মানচিত্রের পরিসীমা ব্যবহার করতে পারেন, যেমন:

// Swift 3
enum EstimateItemStatus: Int {
    case pending = 1,
    onHold
    done
}

let estimateItemStatusValues: [EstimateItemStatus?] = (EstimateItemStatus.pending.rawValue...EstimateItemStatus.done.rawValue).map { EstimateItemStatus(rawValue: $0) }

এটি স্ট্রিং বা সংখ্যা ব্যতীত অন্য যে কোনও কিছুর সাথে যুক্ত এনামগুলির সাথে পুরোপুরি কাজ করে না, তবে যদি এটি হয় তবে এটি দুর্দান্ত কাজ করে!


0

AllValues ​​তৈরি করার জন্য একটি এনমোতে প্রসারিত।

extension RawRepresentable where Self: CaseIterable {
      static var allValues: [Self.RawValue] {
        return self.allCases.map { $0.rawValue}
      }
    }

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