# seq.stateMap(\_:\_:)

{% tabs %}
{% tab title="stateMap()" %}
![](https://1830103165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5-JmwCZMKh_d7RfBaN%2Fuploads%2FMDuYR2bHgZMSA3QmAlbq%2FstateMap.png?alt=media\&token=51cffc82-5464-46ac-b06a-90e1835d0a03)

```swift
extension Sequence {
    /// `seq.stateMap(_:_:)`:
    /// map a sequence with a local state.
    public func stateMap<State, Result>(
        // intial local state
        _ initialState: State, 
        // calculate the result from current element & state,
        // state may be updated upon each call.
        _ result: (inout State, Element) -> Result
    ) -> [Result] { 
        var state = initialState
        return map { elem in 
            return result(&state, elem)
        } 
    }
}
```
{% endtab %}

{% tab title="💈範例" %}
```swift
// example dictionary
let dict = [
    "Sam": 79, "Joe": 5, "Mary": 79,
    "Tom": 5, "Alex": 82, "Nancy": 1
]

typealias State  = (prev: Int?, currentRank: Int, index: Int)
typealias Result = (name: String, score: Int, rank: Int)

let intialState: State = (prev: nil, currentRank: 0, index: 0)

let list = dict
    .sorted { $0.value > $1.value }
    // ⭐️ calculate next result from state & current element,
    //    update local state (if necessary) and return next result.
    .stateMap(intialState) { (state: inout State, elem) -> Result in
        // increase index
        state.index += 1
        // if elem.value is not the same as previous score,
        // update previous score and current rank
        if state.prev == nil || elem.value != state.prev! {
            state.prev = elem.value
            state.currentRank = state.index
        }
        return (elem.key, elem.value, state.currentRank)
    }

print(list)
/*
     [
         (name: "Alex" , score: 82, rank: 1), 
         (name: "Sam"  , score: 79, rank: 2), 
         (name: "Mary" , score: 79, rank: 2),    // no 3rd place
         (name: "Joe"  , score:  5, rank: 4), 
         (name: "Tom"  , score:  5, rank: 4),    // no 5th place
         (name: "Nancy", score:  1, rank: 6)
     ]
 */
```
{% endtab %}

{% tab title="📘 手冊" %}
* [Sequence](https://developer.apple.com/documentation/swift/sequence) ⟩
  * [.map(\_:)](https://developer.apple.com/documentation/swift/sequence/3018373-map)
  * [.reduce()](https://developer.apple.com/documentation/swift/sequence/2907677-reduce)
  * [.reduce(into:\_:)](https://developer.apple.com/documentation/swift/sequence/3128812-reduce)
{% endtab %}

{% tab title="📗 參考" %}
* Advanced Swift (2019.05), p. 34
{% endtab %}

{% tab title="🗣 討論" %}
* [Swift ranking dictionary](https://stackoverflow.com/questions/56513736/swift-ranking-dictionary/70348958#70348958)
{% endtab %}

{% tab title="👥 相關" %}
* [ranking-list](../../../algorithms/sort/ranking-list "mention")
* [seq.reduce-into-\_](seq.reduce-into-_ "mention")
{% endtab %}
{% endtabs %}
