【问题标题】:Turning an array of a sorted dictionary back into a dictionary将排序字典的数组转换回字典
【发布时间】:2020-10-09 17:13:00
【问题描述】:

我有一本[String : CustomUserInfo] 字典。键是唯一 ID,值是包含用户信息的自定义对象,例如 displayName。自定义对象CustomUserInfo 符合ComparableHashable

我正在搜索一个字符串,并且只希望返回三个键值对。

首先我通过displayName 过滤字典。这给了我一个新字典,其中所有键值对都等于或大于我正在搜索的字符串。

其次,我按displayName 对字典进行排序,这给了我一个数组。每个元素都包含一个键值对。

如果数组中的元素超过三个,则删除其余元素。这给我留下了一个包含三个元素的数组。

问题是,如何将这个数组转换回字典?

替代方案:有没有办法将.filter 之后的闭包中的代码更改为只返回三个最相关的结果?跳过整个往返数组并返回字典。

我确实需要它,因为我的部分代码需要通过其键访问 CustomUserInfo 对象。

这是我的代码的简化游乐场版本:

import UIKit

    //MARK: - Struct containing the static user dictionary.

    struct Users {
        static var users: [String : CustomUserInfo] = [

        "cjry" : CustomUserInfo(displayName: "Luke"),
        "sorg" : CustomUserInfo(displayName: "Leia"),
        "vhue" : CustomUserInfo(displayName: "Yoda"),
        "sjdy" : CustomUserInfo(displayName: "Vader"),
        "vgdr" : CustomUserInfo(displayName: "Chewbacca"),
        "awdr" : CustomUserInfo(displayName: "Han")
    ]
}

//MARK: - CustomUserInfo object

struct CustomUserInfo {
    var displayName: String
}

extension CustomUserInfo: Comparable, Hashable {
    static func < (lhs: CustomUserInfo, rhs: CustomUserInfo) -> Bool {
        return lhs.displayName.lowercased() < rhs.displayName.lowercased()
    }
}

//MARK: - The search by string method.

func searchUsers(by searchString: String) {

    let searchString = searchString.lowercased()

    let filteredUsers = Users.users.filter { $0.1.displayName.lowercased() >= searchString }
    var sortedUsers = filteredUsers.sorted { $0.1 < $1.1  }
    if sortedUsers.count > 3 {
        sortedUsers.removeLast(sortedUsers.count - 3)
    }

    //sortedUsers is of type [Dictionary<String, CustomUserInfo>.Element] but needs to be [String : CustomUserInfo]
    print(sortedUsers)

}

searchUsers(by: "Ha")

【问题讨论】:

    标签: arrays swift sorting dictionary filter


    【解决方案1】:

    您可以使用reduce 将其转换回字典,并进行一些其他更改,我会将函数编写为

    func searchUsers(by searchString: String) {
        let searchString = searchString.lowercased()
    
        let result = Users.users.filter { $0.1.displayName.lowercased() >= searchString }
            .sorted { $0.1 < $1.1 }
            .prefix(3)
            .reduce(into: [:]) { $0[$1.key] = $1.value }
    
        print(result)
    }
    

    【讨论】:

    • 这很短很优雅!正常工作。另一种解决方案是使用let dictOfUsers = Dictionary(uniqueKeysWithValues: sortedUsers.lazy.map { ($0.key, $0.value) }),但这有点长。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 1970-01-01
    相关资源
    最近更新 更多