首页 > 解决方案 > Swift 中的游程编码更容易阅读吗?

问题描述

任何人都可以用 swift 编写比下面更容易阅读的运行长度编码代码,或者至少解释我从 rosettecode.org 获得的代码吗?这是输入和输出和代码

// "WWWBWW" -> [(3, W), (1, B), (2, W)]

func encode(input: String) -> [(Int, Character)] {
    return input.characters.reduce([(Int, Character)]()) {
        if $0.last?.1 == $1 { var r = $0; r[r.count - 1].0++; return r }
        return $0 + [(1, $1)]
    }
}

标签: swiftrun-length-encoding

解决方案


如果您改用 reduce(into:) 会更容易理解:

func encode(input: String) -> [(Int, Character)] {
    input.reduce(into: [(Int, Character)]()) {
        // if the second element of the last tuple of the result is equal to the current element (character) of the collection
        if $0.last?.1 == $1 {
            // increase the first element of the last tuple tuple of the result
            $0[$0.index(before: $0.endIndex)].0 += 1 
        } else {
            // otherwise add a new tuple with a value of 1 and the current element (character) to the result
            $0 += CollectionOfOne((1, $1))
        }
    }
}

encode(input: "WWWBWW")  // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]

您还可以扩展 Collection 并实现通用方法/属性

extension Collection where Element: Equatable {
    var groupped: [(Int, Element)] {
        reduce(into: []) {
            if $0.last?.1 == $1 {
                $0[$0.index(before: $0.endIndex)].0 += 1
            } else {
                $0 += CollectionOfOne((1, $1))
            }
        }
    }
}

"WWWBWW".groupped    // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]

推荐阅读