如何在 Swift 中一行代码解决数组转字典的问题

发布于: 2019-06-13 16:52
阅读: 519
评论: 4
喜欢: 1

Model数组转字典是业务开发中的常规操作。这个常规操作,你会怎么做呢?

这里是我们的Model

struct Data {
    var name: String
}

现在我们来创建一系列假数据:

var dataList = Array(0..<10).map { Data.init(name: "data \($0)") }

好了,现在我们有了一个Array<Data>,现在我们需要以它的namekey,它本身作为value,放到一个数组里,该怎么做呢?

同学甲:我会。

var dataMap = Dictionary<String, Data>()

for i in 0..<dataList.count {
    dataMap[dataList[i].name] = dataList[i]
}

同学乙:太不优雅了,看我的。

var dataMap = Dictionary<String, Data>()

for data in dataList {
    dataMap[data.name] = data
}

以上都是常规操作,现在看看我的,一行代码可以解决这个问题。

var dataMap = Dictionary.init(dataList.map { ($0.name, $0) }) { $1 }

这一行代码到底是什么意思呢?

首先把方法写全了看。

let dataPairList = dataList.map { ($0.name, $0) }
dataMap = Dictionary.init(dataPairList, uniquingKeysWith: { (old, new) in
    new
})
  • 第一行里,把 key 和 value 拆成了键值对(元组),结果就是下面构造方法的第一个参数。
  • 第二行里,构造方法的第二个参数是一个闭包,用来决定当键重复时,用哪个当值。在例子里直接使用新的 model 覆盖旧的。然后直接构造字典。

Dictionary 的这个构造方法的签名是:

public init<S>(_ keysAndValues: S, uniquingKeysWith combine: ([Key : Value].Value, [Key : Value].Value) throws -> [Key : Value].Value) rethrows where S : Sequence, S.Element == (Key, Value)

这个方法由 Swift 4 引入。

一行代码解决业务开发的常规操作,就是可读性不咋地。


Thanks for reading.

All the best wishes for you! 💕



1 楼

nuomi1

保留 uniquingKeysWith 可读性还行,直接尾随闭包就有点难受。

发表于 2019-06-13 16:58:10 引用
2 楼

Yuu

引用了以下评论:
1 楼

nuomi1

保留 uniquingKeysWith 可读性还行,直接尾随闭包就有点难受。

发表于 2019-06-13 16:58:10

是的没错,所以如果用还是建议留着。

发表于 2019-06-13 17:01:18 引用
3 楼

nuomi1

引用了以下评论:
2 楼

Yuu

[引用 1 楼]
是的没错,所以如果用还是建议留着。

发表于 2019-06-13 17:01:18

``` swift
extension URL {

var monkeyking_queryDictionary: [String: String] {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems
else {
return [:]
}

let items = queryItems.compactMap { $0.value != nil ? ($0.name, $0.value!) : nil }
let dict = Dictionary(items, uniquingKeysWith: { _, last in last })

return dict
}
}
```

类似的应用,使用了 compactMap 过滤 value 为 nil 的元组😆

发表于 2019-06-13 17:24:57 引用
4 楼

yuu

引用了以下评论:
3 楼

nuomi1

[引用 2 楼]
``` swift
extension URL {

var monkeyking_queryDictionary: [String: String] {
guard
let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
let queryItems = components.queryItems
else {
return [:]
}

let items = queryItems.compactMap { $0.value != nil ? ($0.name, $0.value!) : nil }
let dict = Dictionary(items, uniquingKeysWith: { _, last in last })

return dict
}
}
```

类似的应用,使用了 compactMap 过滤 value 为 nil 的元组😆

发表于 2019-06-13 17:24:57

👍👍👍👍

发表于 2019-06-13 17:27:22 引用