swift如何进行分组根据独特的属性值的字典数组?

标签: ios Swift
发布时间: 2017/3/6 23:16:19
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

这是我所拥有的词典响应我从 API 获取一个数组︰

var response = [
["title": "First one", "code": "the_first", "category": "Entertainment category"], 
["title": "Second one", "code": "the_second", "category": "Entertainment category"], 
["title": "Third one", "code": "the_third", "category": "News category"], 
["title": "Fourth one", "code": "the_fourth", "category": "News category"], 
["title": "Fifth one", "code": "the_fifth", "category": "Children category"], 
["title": "Sixth one", "code": "the_sixth", "category": "Children category"]
]

我必须是︰

var channels_by_category = [
["title":"Entertainment category", 
"channels":[
["title": "First one", "code": "the_first", "category": "Entertainment category"],
["title": "Second one", "code": "the_second", "category": "Entertainment category"]
]],

["title":"News category", 
"channels":[
"title": "Third one", "code": "the_third", "category": "News category"],
["title": "Fourth one", "code": "the_fourth", "category": "News category"]
]]
],

["title":"Children category", 
"channels":[
["title": "Fifth one", "code": "the_fifth", "category": "Children category"],
["title": "Sixth one", "code": "the_sixth", "category": "Children category"]
]]
]

在 JavaScript 的世界,我会用 lodash 来绕过这个问题。不过,我没有足够的经验在 Swift 。我想这应该是某种组合 for 循环和 reduce 但我想不出如何去做。

如何实现我想要?

谢谢

解决方法 1:

因为已经提供了很好的答案,你的问题我在这里建议一个不同的解决方案

你不应该对你的数据模型使用词典。此解决方案演示如何使用结构。

显示

首先,让我们定义一个结构来表示您的数据模型

struct Show {
    let title: String
    let code: String
    let category: String

    init?(dict:[String:String]) {
        guard let
            title = dict["title"],
            code = dict["code"],
            category = dict["category"]
            else { return nil }
        self.title = title
        self.code = code
        self.category = category
    }
}

组织您的数据

接下来让我们来将原始数据转换为列表的Show(s)

let shows = response.flatMap(Show.init)

分组

最后让我们按类别分组列表

let categories: [String:[Show]] = shows.reduce([String:[Show]]()) { (categories, show) -> [String:[Show]] in
    var categories = categories
    categories[show.category] = (categories[show.category] ?? []) + [show]
    return categories
}

现在类别有类别名称作为键和一个列表 Show(s) 作为值。

更新 1︰ 遍历列表Show(s)

if let shows = categories["News category"] {
    for show in shows {
        print(show.title)
    }
}

categories["News category"]?.forEach { show in
    print(show.title)
}

更新 2︰ 遍历类别

for elm in categories {
    let category = elm.0
    let shows = elm.1

    print("Category \(category) has \(shows.count) shows")
    shows.forEach { show in
        print(" - \(show.title)")
    }
}

结果

Category News category has 2 shows
 - Third one
 - Fourth one
Category Entertainment category has 2 shows
 - First one
 - Second one
Category Children category has 2 shows
 - Fifth one
 - Sixth one
赞助商