আমি কীভাবে সুইফটে টাইপ করা অ্যারেগুলি বাড়িয়ে দিতে পারি?


203

আমি কীভাবে সুইফটগুলি প্রসারিত করতে পারি Array<T>বা T[]কাস্টম ফাংশনাল ইউজগুলির সাথে টাইপ করব?

সুইফটের এপিআই ডক্সের চারপাশে ব্রাউজ করা দেখায় যে অ্যারে পদ্ধতিগুলি এক্সটেনশন T[], যেমন:

extension T[] : ArrayType {
    //...
    init()

    var count: Int { get }

    var capacity: Int { get }

    var isEmpty: Bool { get }

    func copy() -> T[]
}

একই উত্স অনুলিপি করা এবং আটকানোর সময় এবং এর মতো কোনও পরিবর্তনের চেষ্টা করার সময়:

extension T[] : ArrayType {
    func foo(){}
}

extension T[] {
    func foo(){}
}

এটি ত্রুটিটি দিয়ে তৈরি করতে ব্যর্থ:

নামমাত্রার ধরণ T[]বাড়ানো যায় না

সম্পূর্ণ টাইপ সংজ্ঞা ব্যবহার করে ব্যর্থ হয় Use of undefined type 'T', অর্থাত:

extension Array<T> {
    func foo(){}
}

এবং এটি সঙ্গে ব্যর্থ Array<T : Any>এবং Array<String>

কৌতূহলীভাবে সুইফট আমাকে এগুলি দিয়ে একটি টাইপযুক্ত অ্যারে প্রসারিত করতে দেয়:

extension Array {
    func each(fn: (Any) -> ()) {
        for i in self {
            fn(i)
        }
    }
}

যা এটি আমাকে কল করতে দেয়:

[1,2,3].each(println)

তবে আমি কোনও জেনেরিক প্রকারের এক্সটেনশন তৈরি করতে পারি না কারণ পদ্ধতিটি প্রবাহিত হওয়ার পরে ধরণটি হারাতে পারে বলে মনে হয়, উদাহরণস্বরূপ সুইফটের অন্তর্নির্মিত ফিল্টারটি প্রতিস্থাপনের চেষ্টা করে :

extension Array {
    func find<T>(fn: (T) -> Bool) -> T[] {
        var to = T[]()
        for x in self {
            let t = x as T
            if fn(t) {
                to += t
            }
        }
        return to
    }
}

তবে সংকলকটি এটিকে টাইপযুক্ত হিসাবে বিবেচনা করে যেখানে এটি এখনও এর সাথে এক্সটেনশানটিকে কল করার অনুমতি দেয়:

["A","B","C"].find { $0 > "A" }

এবং যখন কোনও ডিবাগার দিয়ে স্টেপ-থ্রু টাইপটি নির্দেশ করে Swift.Stringতবে এটি Stringপ্রথমে ingালাই ছাড়াই স্ট্রিংয়ের মতো অ্যাক্সেস করার চেষ্টা করা একটি বিল্ড ত্রুটি ie

["A","B","C"].find { ($0 as String).compare("A") > 0 }

বিল্ট-ইন এক্সটেনশনের মতো কাজ করে এমন টাইপড এক্সটেনশন পদ্ধতি তৈরির সঠিক উপায়টি কি কেউ জানেন?


ভোট দিয়েছি কারণ আমি নিজেও উত্তর খুঁজে পাচ্ছি না। extension T[]এক্সকোডে অ্যারে টাইপ করতে কমান্ড-ক্লিক করার সময় একই বিটটি দেখছেন , তবে ত্রুটি না পেয়ে এটি প্রয়োগের কোনও উপায় দেখছেন না।
ইউজারনেম টিবিডি

@ ইউজারনেটবিডি এফওয়াইআই সবেমাত্র এটি খুঁজে পেয়েছে, দেখে মনে হচ্ছে সমাধানের <T>পদ্ধতিটি স্বাক্ষর থেকে সরিয়ে নেওয়া হয়েছিল।
পুরাণ

উত্তর:


296

ক্লাসগুলির সাথে টাইপযুক্ত অ্যারেগুলি বাড়ানোর জন্য , নীচে আমার জন্য কাজ করে (সুইফট ২.২ ) উদাহরণস্বরূপ, একটি টাইপযুক্ত অ্যারে বাছাই করা:

class HighScoreEntry {
    let score:Int
}

extension Array where Element == HighScoreEntry {
    func sort() -> [HighScoreEntry] {
      return sort { $0.score < $1.score }
    }
}

স্ট্রাক্ট বা টাইপালিয়াস দিয়ে এটি করার চেষ্টা করলে একটি ত্রুটি ঘটবে :

Type 'Element' constrained to a non-protocol type 'HighScoreEntry'

আপডেট :

অ-শ্রেণীর সাথে টাইপ করা অ্যারেগুলি বাড়ানোর জন্য নিম্নলিখিত পদ্ধতিটি ব্যবহার করুন:

typealias HighScoreEntry = (Int)

extension SequenceType where Generator.Element == HighScoreEntry {
    func sort() -> [HighScoreEntry] {
      return sort { $0 < $1 }
    }
}

ইন সুইফট 3 কিছু ধরনের নতুন নামকরণ করা হয়েছে:

extension Sequence where Iterator.Element == HighScoreEntry 
{
    // ...
}

1
সংকলক রিপোর্ট করে যে 'সিকোয়েন্সটাইপ' নামটি 'সিকোয়েন্স'
স্যান্ডওভার

আপনি কেন আইট্রেটর ব্যবহার করেন নি [Iterator.Element]? ফেরতের প্রকারে এলিমেন্ট ?
gauussblurinc

1
হাই, আপনি কি 4.1 এ শর্তাধীন কনফারেন্স বৈশিষ্ট্যটি ব্যাখ্যা করতে পারেন? ৪.১-এ নতুন কী? আমরা এটি ২.২-এ করতে পারি? আমি কী অনুপস্থিত
osrl

যেহেতু সুইফ্ট ৩.১ আপনি নিম্নোক্ত সিনট্যাক্স সহ অ-শ্রেণীর সাথে অ্যারেগুলি বাড়িয়ে দিতে পারেন: এক্সটেনশন অ্যারে যেখানে এলিমেন্ট == ইন
গাইলস

63

কিছুক্ষণ চেষ্টা করার পরে সমাধানটি মনে হচ্ছে <T>এর স্বাক্ষর থেকে এইটিকে সরিয়ে ফেলবে :

extension Array {
    func find(fn: (T) -> Bool) -> [T] {
        var to = [T]()
        for x in self {
            let t = x as T;
            if fn(t) {
                to += t
            }
        }
        return to
    }
}

যা এখন বিল্ড ত্রুটিগুলি ব্যতীত উদ্দেশ্য হিসাবে কাজ করে:

["A","B","C"].find { $0.compare("A") > 0 }

1
বিটিডব্লিউ আপনি এখানে যা সংজ্ঞায়িত করেছেন তা filterlet x = ["A","B","C","X”].filter { $0.compare("A") > 0 }
কার্যত


4
আমি দেখি. ডাবল ফিল্টারিং বরং আমাকে বগী বলে মনে হয় ... কিন্তু এটি এখনও ঝুলিতে যে filterহয় বৈশিষ্ট্যগুলি সমতুল্য আপনার টু find, অর্থাত্ ফাংশনের ফলাফলের একই। আপনার ফিল্টার বন্ধের যদি পার্শ্ব-প্রতিক্রিয়া থাকে তবে আপনি অবশ্যই ফলাফল পছন্দ করতে পারেন না।
Palimondo

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

4
আমরা কার্যকরী শব্দের সংজ্ঞা নিয়ে বিতর্ক করছি বলে মনে হচ্ছে । প্রথাগতভাবে, ফাংশনাল প্রোগ্রামিং দৃষ্টান্তে যেখানে filter, mapএবং reduceফাংশনগুলি উত্পন্ন হয়, ফাংশনগুলি তাদের রিটার্ন মানগুলির জন্য নির্বাহ করা হয়। বিপরীতে, eachআপনি উপরে যে ফাংশনটি সংজ্ঞায়িত করেছেন তা হ'ল তার পার্শ্ব-প্রতিক্রিয়ার জন্য নির্বাহ করা একটি ফাংশনের উদাহরণ, কারণ এটি কিছুই দেয় না। আমি অনুমান করি যে আমরা একমত হতে পারি যে বর্তমান সুইফট বাস্তবায়ন আদর্শ নয় এবং ডকুমেন্টেশনে তার রানটাইম বৈশিষ্ট্যগুলি সম্পর্কে কিছু জানায় না।
Palimondo

24

সকল প্রকার প্রসারিত করুন :

extension Array where Element: Comparable {
    // ...
}

কিছু প্রকার প্রসারিত করুন :

extension Array where Element: Comparable & Hashable {
    // ...
}

একটি নির্দিষ্ট ধরণের প্রসারিত করুন :

extension Array where Element == Int {
    // ...
}

8

আমারও অনুরূপ সমস্যা ছিল - একটি সাধারণ অ্যারিকে একটি অদলবদল () পদ্ধতি দিয়ে প্রসারিত করতে চেয়েছিলাম, যা অ্যারের মতো একই ধরণের একটি আর্গুমেন্ট নেওয়ার কথা ছিল। তবে আপনি জেনেরিক প্রকারটি কীভাবে নির্দিষ্ট করবেন? আমি পরীক্ষার এবং ত্রুটি দ্বারা খুঁজে পেয়েছি যে নীচে কাজ করেছে:

extension Array {
    mutating func swap(x:[Element]) {
        self.removeAll()
        self.appendContentsOf(x)
    }
}

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

সেখানে কী চলছে তা আমি 100% নিশ্চিত নই, তবে আমার ধারণা এটি সম্ভবত কারণ 'এলিমেন্ট' অ্যারে সম্পর্কিত একটি প্রকারের (এখানে 'অ্যাসোসিয়েটেড টাইপস' দেখুন https://developer.apple.com/library/ios/docamentation / সুইট / কনসেপ্টুয়াল / সুইফট_প্রগ্রামিং_ ভাষা / জেনারিক্স এইচটিএমএল#//apple_ref/doc/uid/TP40014097-CH26-ID189 )

যাইহোক, আমি কোনো (অ্যারে গঠন রেফারেন্স এই রেফারেন্স দেখতে পারে না https://developer.apple.com/library/prerelease/ios/documentation/Swift/Reference/Swift_Array_Structure/index.html#//apple_ref/swift / স্ট্রাক্ট / গুলি: সা ) ... তাই আমি এখনও কিছুটা অনিশ্চিত।


1
Arrayজেনেরিক টাইপ: Array<Element>( swiftdoc.org/v2.1/type/Array দেখুন ), Elementঅন্তর্ভুক্ত প্রকারের জন্য একটি স্থানধারক। উদাহরণস্বরূপ: এর var myArray = [Foo]()অর্থ myArrayকেবলমাত্র টাইপ থাকবে FooFooএক্ষেত্রে জেনেরিক স্থানধারীর কাছে "ম্যাপ করা" Element। আপনি যদি অ্যারের সাধারণ আচরণটি (এক্সটেনশনের মাধ্যমে) পরিবর্তন করতে চান তবে আপনি জেনেরিক প্লেসোল্ডার ব্যবহার করবেন Elementএবং কোনও কংক্রিটের ধরণ নয় (ফু এর মতো)।
ডেভিড জেমস

5

সুইফট ২.২ ব্যবহার করে : স্ট্রিংগুলির অ্যারে থেকে সদৃশগুলি সরিয়ে দেওয়ার চেষ্টা করার সময় আমি একই ধরণের সমস্যায় পড়েছি। আমি অ্যারে ক্লাসে একটি এক্সটেনশান যুক্ত করতে সক্ষম হয়েছিল যা আমি যা করতে চাইছিলাম তা করে।

extension Array where Element: Hashable {
    /**
     * Remove duplicate elements from an array
     *
     * - returns: A new array without duplicates
     */
    func removeDuplicates() -> [Element] {
        var result: [Element] = []
        for value in self {
            if !result.contains(value) {
                result.append(value)
            }
        }
        return result
    }

    /**
     * Remove duplicate elements from an array
     */
    mutating func removeDuplicatesInPlace() {
        var result: [Element] = []
        for value in self {
            if !result.contains(value) {
                result.append(value)
            }
        }
        self = result
    }
}

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

 var dupes = ["one", "two", "two", "three"]
 let deDuped = dupes.removeDuplicates()
 dupes.removeDuplicatesInPlace()
 // result: ["one", "two", "three"]

এটিও সম্পন্ন হতে পারে let deDuped = Set(dupes), যা আপনি toSetযতক্ষণ না টাইপ পরিবর্তনের সাথে ঠিক আছেন ততক্ষণ একটি অ-ধ্বংসাত্মক পদ্ধতিতে ফিরে আসতে পারেন
alexpyoung

@alexpyoung আপনি অ্যারে ক্রমটি নষ্ট করবেন যদি আপনি সেট () করেন
ড্যানি ওয়াং

5

আপনি যদি এই গিথুব রেপোতে ক্লাস চেকআউট কোডে অ্যারে এবং অন্যান্য ধরণের বিল্ড বাড়ানোর বিষয়ে জানতে চান তবে https://github.com/ankurp/Cent

এক্সকোড 6.1 হিসাবে অ্যারেগুলি বাড়ানোর সিনট্যাক্সটি নিম্নরূপ

extension Array {
    func at(indexes: Int...) -> [Element] {
        ... // You code goes herer
    }
}

1
@ রব ইউআরএল আপডেট করেছেন
পিটিএল

3

আমি সুইফট 2 স্ট্যান্ডার্ড লাইব্রেরির শিরোনামগুলিতে এক নজর পেয়েছি এবং এখানে ফিল্টার ফাংশনটির প্রোটোটাইপ রয়েছে, এটি কীভাবে আপনার নিজের রোল করতে হবে তা বেশ স্পষ্ট করে তোলে makes

extension CollectionType {
    func filter(@noescape includeElement: (Self.Generator.Element) -> Bool) -> [Self.Generator.Element]
}

এটি অ্যারের কোনও এক্সটেনশান নয়, কালেকশন টাইপ, সুতরাং একই পদ্ধতিটি অন্যান্য সংগ্রহের ধরণের ক্ষেত্রেও প্রযোজ্য। @ নয়েসके্যাপের অর্থ হ'ল পাসকৃত ব্লকটি ফিল্টার ফাংশনের সুযোগ ছাড়বে না, যা কিছু অপটিমাইজেশন সক্ষম করে। একটি মূলধন এস সহ স্বয়ং যে শ্রেণিটি আমরা প্রসারিত করছি। সেলফ.জেনেটর এমন একটি পুনরাবৃত্তি যা সংগ্রহের মধ্যে থাকা বস্তুর মাধ্যমে পুনরাবৃত্তি করে এবং সেলফ-জেনারেটর.এলিমেন্টটি বস্তুর প্রকার, উদাহরণস্বরূপ একটি অ্যারের [অন্ত?] সেলফ.জেনেটর.এলিমেন্টটি ইন্টার ?.

এই সমস্ত ফিল্টার পদ্ধতিতে যে কোনও কালেকশন টাইপের ক্ষেত্রে প্রয়োগ করা যেতে পারে, এর জন্য একটি ফিল্টার ব্লক প্রয়োজন যা সংগ্রহের একটি উপাদান নেয় এবং একটি বুল ফেরত দেয়, এবং এটি মূল ধরণের একটি অ্যারে প্রদান করে। সুতরাং এটি একত্রে রাখার জন্য, এখানে একটি পদ্ধতি যা আমি দরকারী বলে মনে করি: এটি মানচিত্র এবং ফিল্টারকে একত্রিত করে, একটি ব্লক গ্রহণ করে যা সংগ্রহের উপাদানটিকে একটি বিকল্প বিকল্পকে মানচিত্র করে এবং শূন্য নয় এমন alচ্ছিক মানগুলির একটি অ্যারে প্রদান করে।

extension CollectionType {

    func mapfilter<T>(@noescape transform: (Self.Generator.Element) -> T?) -> [T] {
        var result: [T] = []
        for x in self {
            if let t = transform (x) {
                result.append (t)
            }
        }
        return result
    }
}


0

( সুইফট ২.x )

জেনেরিক ধরণের পদ্ধতির জন্য নীল-আরপিন্ট সম্বলিত একটি প্রোটোকলের সাথে সামঞ্জস্য রাখতে আপনি অ্যারে প্রসারিত করতে পারেন, যেমন, কোনও প্রকারের সীমাবদ্ধতা অনুসারে সমস্ত জেনেরিক অ্যারে উপাদানগুলির জন্য আপনার কাস্টম ফাংশনাল ইউজযুক্ত একটি প্রোটোকল, বলুন প্রোটোকল MyTypes। এই পদ্ধতির সাহায্যে বোনাসটি হ'ল আপনি জেনেরিক অ্যারে আর্গুমেন্ট গ্রহণ করে ফাংশন লিখতে পারেন, এই সীমাবদ্ধতার সাথে এই অ্যারে আর্গুমেন্টগুলি আপনার কাস্টম ফাংশন ইউটিলিটি প্রোটোকলের সাথে খাপ খায়, প্রোটোকল বলে MyFunctionalUtils

আপনি এই আচরণটি সুস্পষ্টভাবে পেতে পারেন, অ্যারে উপাদানগুলিকে সীমাবদ্ধ করে টাইপ করে MyTypes, বা --- যেমন আমি নীচে বর্ণিত পদ্ধতিতে দেখাব ---, খুব ঝরঝরে, স্পষ্টভাবে, আপনার জেনেরিক অ্যারে ফাংশন শিরোনামকে সরাসরি ইনপুট অ্যারে প্রদর্শন করতে দেয় অনুসারে MyFunctionalUtils


প্রোটোকল দিয়ে MyTypesটাইপ সীমাবদ্ধতা হিসাবে ব্যবহারের জন্য আমরা শুরু করি ; এই প্রোটোকল দ্বারা ধরনের আপনি আপনার জেনেরিক্স মাপসই করতে চান প্রসারিত (উদাহরণস্বরূপ নিচের মৌলিক ধরনের প্রসারিত Intএবং Doubleসেইসাথে একটি কাস্টম টাইপ MyCustomType)

/* Used as type constraint for Generator.Element */
protocol MyTypes {
    var intValue: Int { get }
    init(_ value: Int)
    func *(lhs: Self, rhs: Self) -> Self
    func +=(inout lhs: Self, rhs: Self)
}

extension Int : MyTypes { var intValue: Int { return self } }
extension Double : MyTypes { var intValue: Int { return Int(self) } }
    // ...

/* Custom type conforming to MyTypes type constraint */
struct MyCustomType : MyTypes {
    var myInt : Int? = 0
    var intValue: Int {
        return myInt ?? 0
    }

    init(_ value: Int) {
        myInt = value
    }
}

func *(lhs: MyCustomType, rhs: MyCustomType) -> MyCustomType {
    return MyCustomType(lhs.intValue * rhs.intValue)
}

func +=(inout lhs: MyCustomType, rhs: MyCustomType) {
    lhs.myInt = (lhs.myInt ?? 0) + (rhs.myInt ?? 0)
}

প্রোটোকল MyFunctionalUtils(আমাদের অতিরিক্ত জেনেরিক অ্যারে ফাংশন ইউটিলিটিগুলি ব্লুপ্রিন্টগুলি ধারণ করে) এবং এরপরে, অ্যারের দ্বারা এক্সটেনশন MyFunctionalUtils; নীল-মুদ্রিত পদ্ধতির প্রয়োগ:

/* Protocol holding our function utilities, to be used as extension 
   o Array: blueprints for utility methods where Generator.Element 
   is constrained to MyTypes */
protocol MyFunctionalUtils {
    func foo<T: MyTypes>(a: [T]) -> Int?
        // ...
}

/* Extend array by protocol MyFunctionalUtils and implement blue-prints 
   therein for conformance */
extension Array : MyFunctionalUtils {
    func foo<T: MyTypes>(a: [T]) -> Int? {
        /* [T] is Self? proceed, otherwise return nil */
        if let b = self.first {
            if b is T && self.count == a.count {
                var myMultSum: T = T(0)

                for (i, sElem) in self.enumerate() {
                    myMultSum += (sElem as! T) * a[i]
                }
                return myMultSum.intValue
            }
        }
        return nil
    }
}

পরিশেষে, পরীক্ষাগুলি এবং দুটি উদাহরণ যথাক্রমে নিম্নলিখিত কেসগুলির সাথে জেনেরিক অ্যারে গ্রহণ করে একটি ফাংশন দেখায়

  1. দেখানো অন্তর্নিহিত কথন যে অ্যারের পরামিতি প্রোটোকল 'MyFunctionalUtils' সাথে সামঞ্জস্য, টাইপ মাধ্যমে 'MyTypes' (ফাংশন অ্যারে উপাদানের constraining bar1)।

  2. সুস্পষ্টভাবে দেখানো হচ্ছে যে অ্যারে প্যারামিটারগুলি 'মাই ফাংশনাল ইউটিলেস' (ফাংশন bar2) প্রোটোকলের সাথে খাপ খায় ।

পরীক্ষা এবং উদাহরণ নিম্নলিখিত:

/* Tests & examples */
let arr1d : [Double] = [1.0, 2.0, 3.0]
let arr2d : [Double] = [-3.0, -2.0, 1.0]

let arr1my : [MyCustomType] = [MyCustomType(1), MyCustomType(2), MyCustomType(3)]
let arr2my : [MyCustomType] = [MyCustomType(-3), MyCustomType(-2), MyCustomType(1)]

    /* constrain array elements to MyTypes, hence _implicitly_ constraining
       array parameters to protocol MyFunctionalUtils. However, this
       conformance is not apparent just by looking at the function signature... */
func bar1<U: MyTypes> (arr1: [U], _ arr2: [U]) -> Int? {
    return arr1.foo(arr2)
}
let myInt1d = bar1(arr1d, arr2d) // -4, OK
let myInt1my = bar1(arr1my, arr2my) // -4, OK

    /* constrain the array itself to protocol MyFunctionalUtils; here, we
       see directly in the function signature that conformance to
       MyFunctionalUtils is given for valid array parameters */
func bar2<T: MyTypes, U: protocol<MyFunctionalUtils, _ArrayType> where U.Generator.Element == T> (arr1: U, _ arr2: U) -> Int? {

    // OK, type U behaves as array type with elements T (=MyTypes)
    var a = arr1
    var b = arr2
    a.append(T(2)) // add 2*7 to multsum
    b.append(T(7))

    return a.foo(Array(b))
        /* Ok! */
}
let myInt2d = bar2(arr1d, arr2d) // 10, OK
let myInt2my = bar2(arr1my, arr2my) // 10, OK

-1
import Foundation

extension Array {

    func calculateMean() -> Double {
        // is this an array of Doubles?
        if self.first is Double {
            // cast from "generic" array to typed array of Doubles
            let doubleArray = self.map { $0 as! Double }

            // use Swift "reduce" function to add all values together
            let total = doubleArray.reduce(0.0, combine: {$0 + $1})

            let meanAvg = total / Double(self.count)
            return meanAvg

        } else {
            return Double.NaN
        }
    }

    func calculateMedian() -> Double {
        // is this an array of Doubles?
        if self.first is Double {
            // cast from "generic" array to typed array of Doubles
            var doubleArray = self.map { $0 as! Double }

            // sort the array
            doubleArray.sort( {$0 < $1} )

            var medianAvg : Double
            if doubleArray.count % 2 == 0 {
                // if even number of elements - then mean average the middle two elements
                var halfway = doubleArray.count / 2
                medianAvg = (doubleArray[halfway] + doubleArray[halfway - 1]) / 2

            } else {
                // odd number of elements - then just use the middle element
                medianAvg = doubleArray[doubleArray.count  / 2 ]
            }
            return medianAvg
        } else {
            return Double.NaN
        }

    }

}

2
এই ডাউনকাস্টগুলি ( $0 as! Double) সুইফটের টাইপ সিস্টেমের বিরুদ্ধে লড়াই করছে এবং আমার মতে ওপি-র প্রশ্নের উদ্দেশ্যকেও পরাস্ত করে। এটি করে আপনি যে গণনাগুলি করতে চান তার জন্য কম্পাইলার অপ্টিমাইজেশনের জন্য কোনও সম্ভাবনা হারাচ্ছেন এবং আপনি অর্থহীন ফাংশনগুলির সাথে অ্যারের নামস্থানটিও দূষিত করছেন (কেন আপনি ইউআইভিউয়ের একটি অ্যারেতে .ক্যালকুলেটমেডিয়ান () দেখতে চান, বা এই বিষয়ে দ্বিগুণ ছাড়া আর কি?)। আরও ভাল উপায় আছে।
এফিমার

চেষ্টা করুনextension CollectionType where Generator.Element == Double {}
এফিমার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.