SwiftでLTSVのパースプログラムを書いてみました【別解求む】

swiftでLTSVをパースするプログラムを作ってみました。
他の解き方も募集しております。

# Rubyの置き換え
[公式サイト](http://ltsv.org)に記載してあったRubyのサンプルを置き換えました。

```ltsv.swift
let str = "name:anonymous\tage:24\tbirthday:1990/10/01"
let d = split(str, {$0 == "\t"}).map{split($0, {$0 == ":"})}.reduce([String:String]()) {
    (var dic, item)in
    dic[item[0]] = item[1]
    return dic
}
println(d)
println(d["name"]!)      // anonymous
println(d["age"]!)       // 24
println(d["birthday"]!)  // 1990/10/01
```

# LTSV Class を作って解いた方法
asStringや、asIntは、[dankogai](http://qiita.com/dankogai)さんが作った[swift-json](http://qiita.com/dankogai/items/e3d9882f4d25bc44cc03)を参考にさせて戴きました。
こちらのコードは、文字列を操作する方法に手間取ってしまいました。

```ltsv2.swift
import UIKit
 
public class Ltsv {
    private let _value: [String: AnyObject]
    
    public init(_ obj: [String: AnyObject]) {
        self._value = obj
    }
}
 
extension Ltsv {
    public func asString(key: String) -> String? {
        switch self._value[key] {
        case let o as NSString:
            return o as String
        default:
            return nil
        }
    }
    
    public func asInt(key: String) -> Int? {
        switch self._value[key] {
        case let o as NSNumber:
            switch String.fromCString(o.objCType)! {
            case "c", "C":
                return nil
            default:
                return Int(o.longLongValue)
            }
        default:
            return nil
        }
    }
    
    public func asDate(key: String) -> NSDate? {
        if let dateString = self._value[key] as? NSString {
            let dateFormatter = NSDateFormatter()
            dateFormatter.dateFormat = "yyyy/MM/dd"
            return dateFormatter.dateFromString(dateString)
        }
        return nil
    }
}
 
class MyLtsv : Ltsv {
    var name: String? {
        return self.asString("name")
    }
    
    var age: Int? {
        return self.asInt("age")
    }
    
    var birthday: NSDate? {
        return self.asDate("birthday")
    }
}
 
extension String {
    func substring(start: Int, var length: Int? = nil) -> String {
        assert(0 <= start)
        
        let max = countElements(self) - start
        if length == nil || length <= 0 || max < length! {
            return self.substringFromIndex(advance(self.startIndex, start))
        }
        
        return self.substringFromIndex(advance(self.startIndex, start)).substringToIndex(advance(self.startIndex, length!))
    }
    func trim() -> String {
        return self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    }
}
 
extension NSDate {
    func tostring(format: String) -> String {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.locale = NSLocale(localeIdentifier: "ja_JP")
        return dateFormatter.stringFromDate(self)
    }
}
 
let str = "name: anonymous\tage: 24\tbirthday: 1990/10/01"
let dic = str.componentsSeparatedByString("\t").reduce([String: String]()){
    (var dic, item) in
    println(item)
    if let index = find(item, ":") {
        let pos: Int = distance(item.startIndex, index)
        let key = item.substring(0, length: pos)
        let value = item.substring(pos + 1).trim()
        println(key)
        println(value)
        dic[key] = value
    }
    return dic
}
 
println(dic)
let ltsv = MyLtsv(dic)
println(ltsv.name!)
println(ltsv.age)
println(ltsv.birthday!.tostring("yyyy/MM/dd"))
```