【问题标题】:Swift - Array to DictionarySwift - 数组到字典
【发布时间】:2020-11-26 06:46:57
【问题描述】:

所以,我有以下对象:

struct Person {
   let name: String
   let birthday: String
}

let Bob = Person(name: "Bob", birthday: "11.12.1987")
let Tim = Person(name: "Tim", birthday: "11.12.1987")
let John = Person(name: "John", birthday: "01.02.1957")
let Jerry = Person(name: "Jerry", birthday: "17.12.2001")

还有以下数组:

let people = [Bob, Tim, John, Jerry]

我的目标是从这个数组中生成一个字典,其中键为“生日”,值为“Person”对象本身:[String: [Person]]。如果有相同的键,则应添加该人并形成一个数组作为键。所以结果如下:

dictionary = ["11.12.1987": [Bob, Tim], "01.02.1957": John, "17.12.2001": Jerry]

实现这一目标的最佳方法是什么?

干杯!

【问题讨论】:

    标签: swift dictionary


    【解决方案1】:

    您可以将Dictionary(grouping:by:) 方法与mapValues 一起使用,

    let result = Dictionary(grouping: people, by: \.birthday)
    
    print(result)
    

    输出是,

    [“01.02.1957”:[“约翰”],“17.12.2001”:[“杰瑞”],“11.12.1987”: [“鲍勃”,“蒂姆”]]

    这将为您生成Dictionary<String, [Person]> 类型的字典。

    从你的问题来看,如果有多个人时只有一个人和数组,你似乎想要一个人。在那种情况下,你会丢失类型,你的类型会是这样的,Dictionary<String, Any>。你可以对上面的代码做一点修改来做到这一点。

    let result = Dictionary(grouping: people, by: \.birthday)
        .mapValues { people -> Any in
                    if people.count == 1 {
                        return people.first!
                    }
                    return people
                }
    
    print(result)
    

    输出将与您想要的相似,

    [“01.02.1957”:“约翰”,“17.12.2001”:“杰瑞”,“11.12.1987”:[“鲍勃”, “蒂姆”]]

    【讨论】:

    • OP 说the "Person" object itself as the value: [String: [Person]] 所以,不需要这么麻烦。只需使用 Dictionary(grouping:by:) 初始化程序即可。
    • 出于某种原因,我似乎错过了您的代码部分:“Dictionary(grouping: people, by: { $0.birthday })” 工作正常,没有 .mapValue 部分。非常感谢
    • 哦,我明白了,您只解析键的名称,而不是对象“Person”
    【解决方案2】:

    如何通过字典循环检查日期是否存在。否则创建带有日期的键并赋值。 如果 key 已经存在,则将 person 添加到实际的 key 值:

    var dictionary = [String: [Person]]()
            
            // Loop through all person objects in array
            for person in people {
                
                // Check if date already exists
                if dictionary[person.birthday] != nil {
                    // If already exists, include new person in array
                    var array = dictionary[person.birthday]
                    array!.append(person)
                }
                // If date does not exists, add new key with date and person
                else {
                    dictionary[person.birthday] = [person]
                }
                
            }
    

    【讨论】:

    • 谢谢,效果很好。但我一直在寻找更“优雅”的做法,就像 Sandeep 建议的那样
    • let dict = Dictionary(grouping: people, by: \.birthday)
    • 这很好,但它正在重新发明一个轮子。每次您复制/粘贴这样的模式时,都会引入错误和错误的机会。您应该尽可能利用标准库。
    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 2015-05-10
    • 2018-07-09
    • 2015-06-15
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多