簡體   English   中英

在Swift中將.filter與字典數組一起使用

[英]Use .filter with array of dictionaries in Swift

我有一個稱為master的數組,它的類型為Array<Dictionary<String, String>>() 我正在嘗試使用過濾器功能,如下所示:

filteredMusic = allSongNames.filter({ (song: String) -> Bool in
    let stringMatch = song.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
    return stringMatch != nil
})

其中filteredMusicallSongNames都是String的數組。 我嘗試使用我的master數組和masterFilter (與master相同的類型)來翻譯此內容:

masterFilter = master.filter({ (song: String, id: String) -> Bool in
    let stringMatch = song.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
    return stringMatch != nil
})

我的錯誤:

'(String, String) -> Bool' is not convertible to '([String : String]) -> Bool'

我一定搞砸了語法。 正確的語法是什么?

在過濾器的閉包中,您接受兩個String參數,但必須改為接受一個[String:String] (即,數組包含的類型: Dictionary<String, String> )。 因此,您需要將過濾器更改為…

masterFilter = master.filter({ (dictionary: [String:String]) -> Bool in
    …
})

因為您的過濾器現在接受字典而不是兩個字符串,所以您需要更改其工作方式。 大概您想遍歷字典來執行搜索,但是確切的實現取決於您要達到的目標。 一個示例可能是:

masterFilter = master.filter({ (dictionary: [String:String]) -> Bool in
    for (song, id) in dictionary {
        if song.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil {
            return true
        }
    }

    return false
})

Array的filter實例方法的類型簽名為

func filter(includeElement: (T) -> Bool) -> [T]

這意味着它接受一個函數,該函數接受類型T的參數並返回truefalse ,並且過濾器實例方法返回類型T的數組,該數組與為其提供的函數參數相同。

第一次使用filter有效的,因為它是String數據類型的數組,而第二個卻不起作用,因為(song: String, id: String)意味着有一個函數具有給filter兩個參數。 編譯器生成的錯誤充分描述了它。 它說類型是字典,因此[String:String]。 因此,為了使其正常工作,您應該采用以下方式:

請記住, Dictionary數據類型具有一個稱為keys的實例變量,該實例變量返回LazyForwardCollection<MapCollectionView<[Key : Value], Key>>類型的LazyForwardCollection<MapCollectionView<[Key : Value], Key>> 定義是

var keys: LazyForwardCollection<MapCollectionView<[Key : Value], Key>> { get }

LazyForwardCollection具有一個實例變量first ,讓你的第一元件,它也具有array ,讓你的所有元素。

var first: S.Generator.Element? { get }

// Let the compiler infer the type though you can give (dict: [String : String]) -> Bool
masterFilter = master.filter { dict in 
        let song = dict.keys.first

        let stringMatch = song.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
        return stringMatch != nil
    }

我沒有使用for-in循環,因為您的代碼顯示的方式(盡管它沒有編譯)顯示在數組內部,但字典中只有一個鍵/值對。 盡管您可以根據需要使用它。

您也沒有使用id 因此,在我看來,您不需要這些值,盡管dictionary的本質是您既需要鍵又需要值,否則Array數據類型將起作用。 一個可能的猜測是,您正在從Web服務器檢索返回JSON或其他符號的數據,因此首先將其轉換為字典,然后使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM