繁体   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