Swift编译器一直工作,直到我添加另一个.map(ping)子句

时间:2016-02-10 22:32:30

标签: swift split

我正在处理一些旧的文本文件,并使用mapreduce对其进行解析。这是一个有效的例子:

onecpart.componentsSeparatedByString(" ")
    .reduce("", combine: { $0 + ($1.containsString(":") ? "\n" : " ") + $1 })
    .componentsSeparatedByString("\n")
    .filter({ $0 != "" })
    .map({ $0.componentsSeparatedByString(":") })
    .forEach({ info[$0.first!] = $0.last })

现在我尝试做一些非常相似的事情,主要区别在于我必须有两个分隔符。所以我这样做了:

let parts = original!.characters.split{ $0 == " " || $0 == "," }
    .map{ String($0).trim() }
    .reduce("", combine: { $0 + ($1.containsString("=") ? "\n" : " ") + $1 })
    .componentsSeparatedByString("\n")

此代码正确解析该行并返回其中包含=的字符串数组,但也返回一些空字符串。所以要摆脱我想要做的空字符串:

let parts = original!.characters.split{ $0 == " " || $0 == "," }
    .map{ String($0).trim() }
    .reduce("", combine: { $0 + ($1.containsString("=") ? "\n" : " ") + $1 })
    .componentsSeparatedByString("\n")
    .filter({ $0 != "" })

现在,当我编译时,它在分析阶段坚持了很长时间,然后没有说:

Expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions

我似乎记得这与类型推断有关,我怀疑是因为使用了characters.split?有没有办法解决这个问题而不会引入太多的复杂性?

2 个答案:

答案 0 :(得分:1)

你可能对.characters令人困惑的编译器感到满意。 这是另一种方法(无法找到trim(),所以我用我认为相同的方法替换它。)

let parts = original!
           .componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: " ,"))     
           .map ({ $0.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString:" ")) })
           .reduce("", combine: { $0 + ($1.containsString("=") ? "\n" : " ") + $1 })
           .componentsSeparatedByString("\n")
           .filter({ $0 != "" })

答案 1 :(得分:0)

对Alain的优秀答案嗤之以鼻,其他人可能会觉得这很有用:

extension String {
    func componentsSeparatedByStrings(delimiters: [String]) -> [String] {
        guard self.length > 0 else { return [] }
        guard delimiters.count > 0 else { return [] }
        let delims = delimiters.joinWithSeparator("")
        return componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: delims))
    }
}

您可以这样称呼它:

let parts = mystring.componentsSearatedByStrings([" ",",","\t"])

您可以在上面的示例中使用该内联,但您不会遇到编译器错误。