2017-06-02 56 views
3

我知道Swift的更高階的函數,比如Map,Filter,Reduce和FlatMap,但我沒有意識到任何類似於'All'或'Any'的返回布爾值的正面測試會短路的同時列舉結果。Swift是否有像Any或All這樣的高階函數短路?

例如,考慮您擁有10,000個對象的集合,每個對象都有一個名爲isFulfilled的屬性,並且您想查看該集合中是否有isFulfilled設置爲false。在C#中,您可以使用myObjects.Any(obj -> !obj.isFulfilled),並且在遇到該情況時,將會使枚舉的其餘部分短路並立即返回true

Swift中有這樣的事嗎?

回答

2

Sequence(並且特別是CollectionArray)具有以布爾謂詞爲參數的(短路)contains(where:)方法。例如,如果

if array.contains(where: { $0 % 2 == 0 }) 

檢查該數組包含任何偶數。

沒有「全部」方法,但是可以通過否定謂詞和結果來使用以及 。例如,

if !array.contains(where: { $0 % 2 != 0 }) 

檢查陣列中的所有數字是偶數。當然你也可以自定義一個擴展方法:

extension Sequence { 
    func allSatisfy(_ predicate: (Iterator.Element) -> Bool) -> Bool { 
     return !contains(where: { !predicate($0) }) 
    } 
} 

如果你想允許「扔」謂詞以同樣的方式作爲 contains方法,然後將它定義爲

extension Sequence { 
    func allSatisfy(_ predicate: (Iterator.Element) throws -> Bool) rethrows -> Bool { 
     return try !contains(where: { try !predicate($0) }) 
    } 
} 
3

另外一個在這種情況下,您可以在Swift中做的與「短路」類似的事情是使用集合的lazy屬性,這會將您的實現更改爲如下所示:

myObjects.lazy.filter({ !$0.isFulfilled }).first != nil 

這與你所要求的並不完全相同,但可能有助於在處理這些高階函數時提供另一種選擇。你可以閱讀更多關於蘋果的文檔lazyhttps://developer.apple.com/reference/swift/array/1782542-lazy

+0

對於Array上的lazy屬性的信息+1。我知道延遲執行直到查詢時間的懶惰屬性,但我不知道這個特定的'視圖'到數組中。我喜歡!謝謝! – MarqueIV

0

如果你有這樣的陣列中的所有對象,他們應該遵循的一些協議,它實現了可變isFulfilled ......你可以看到,你可以把這些對象confrom到(我們稱之爲履行協議)......現在,你可以在這裏施展數組到類型[FulfilledItem] ...現在你可以繼續作爲一般

我粘貼代碼爲您更好地理解:

你看,你不能擴展任何或AnyObject,因爲AnyObject是協議,不能被擴展(我猜想蘋果打算),但你可以,子類「協議或只要你喜歡專業調用它 - 使協議從AnyObject繼承...

protocol FulfilledItem: AnyObject{ 

    var isFulfilled: Bool {get set} 

} 

class itemWithTrueValue: FulfilledItem{ 
    var isFulfilled: Bool = true 
} 

class itemWithFalseValue: FulfilledItem{ 
    var isFulfilled: Bool = false 
} 

var arrayOfFulFilled: [FulfilledItem] = [itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue(),itemWithFalseValue()] 

    let boolValue = arrayOfFulFilled.contains(where: { 
     $0.isFulfilled == false 
    }) 

現在我們已經得到了自己一個非常好看的自定義協議繼承所有的所有屬性+我們美麗的isFulfilled財產,這是我們現在處理的通常...

根據蘋果文檔:

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-ID342

AnyObject僅供參考類型(類),任何對於兩個值類型和引用類型,所以我想這是首選繼承AnyObject ...

現在你投,而不是AnyObject到陣列協議項FulfilledItem,你將有漂亮的解決方案(不要忘記每一個項目,以符合該協議並將其值設置...)

祝快樂編碼:)

+1

感謝您的回覆,但您解決了錯誤的問題。我的問題是詢問Swift中是否有任何短路高階函數。我只是使用isFulfilled作爲一個任意的例子。另外,如果我們談論的是具有isFulfilled屬性的具體類型的同類序列,則無論如何您都不會創建協議,因爲您只需在對象上使用屬性。我沒有說,不管技術上你是否正確。儘管如此,具有諷刺意味的是,你的回答包括我以後的......'包含(其中:)以一種迂迴的方式,你確實回答了它! :) – MarqueIV

相關問題