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

发布于:2019-06-13 16:52,阅读数:950,点赞数:2


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

![](//cdn.yuusann.com/img/posts/17019_5.jpg)

这里是我们的`Model`:

```swift
struct Data {
var name: String
}
```

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

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

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

同学甲:我会。

```swift
var dataMap = Dictionary<String, Data>()

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

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

```swift
var dataMap = Dictionary<String, Data>()

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

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

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

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

![](//cdn.yuusann.com/img/posts/17019_6.jpg)

首先把方法写全了看。

```swift
let dataPairList = dataList.map { ($0.name, $0) }
dataMap = Dictionary.init(dataPairList, uniquingKeysWith: { (old, new) in
new
})
```

- 第一行里,把 key 和 value 拆成了键值对(元组),结果就是下面构造方法的第一个参数。
- 第二行里,构造方法的第二个参数是一个闭包,用来决定当键重复时,用哪个当值。在例子里直接使用新的 model 覆盖旧的。然后直接构造字典。

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

```swift
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 引入。

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


评论:4条


1楼:2019-06-13 16:58:10

nuomi1:

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


2楼:2019-06-13 17:01:18

Yuu:

引用:1楼

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


3楼:2019-06-13 17:24:57

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 的元组?


4楼:2019-06-13 17:27:22

yuu:

引用:3楼

????


返回列表

返回归档

返回主页