SHARE
TWEET

Untitled

a guest May 23rd, 2019 63 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. private extension StringProtocol {
  2.     init(string: String) {
  3.         self = string as! Self
  4.     }
  5. }
  6.  
  7. indirect enum Path {
  8.     case path(key: String, remainingPath: Path)
  9.     case end(key: String)
  10.  
  11.     var key: String {
  12.         switch self {
  13.         case let .path(key, _), let .end(key):
  14.             return key
  15.         }
  16.     }
  17. }
  18.  
  19. extension Path {
  20.     init(_ string: String) {
  21.         let segments = string.split(separator: ".", maxSplits: 1)
  22.         if segments.count > 1 {
  23.             self = .path(key: String(segments.first!), remainingPath: Path(String(segments.last!)))
  24.         } else {
  25.             self = .end(key: string)
  26.         }
  27.     }
  28. }
  29.  
  30. extension Path: ExpressibleByStringLiteral {
  31.     init(stringLiteral value: String) {
  32.         self.init(value)
  33.     }
  34.     init(unicodeScalarLiteral value: String) {
  35.         self.init(value)
  36.     }
  37.     init(extendedGraphemeClusterLiteral value: String) {
  38.         self.init(value)
  39.     }
  40. }
  41.  
  42. extension Path: CustomStringConvertible {
  43.     var description: String {
  44.         switch self {
  45.         case .end(let key):
  46.             return key
  47.         case let .path(key, path):
  48.             return "\(key).\(path.description)"
  49.         }
  50.     }
  51. }
  52.  
  53. extension Dictionary where Key: StringProtocol {
  54.     subscript(path keyPath: Path) -> Any? {
  55.         get {
  56.             let key = Key(string: keyPath.key)
  57.             switch keyPath {
  58.             case let .path(_, remainingPath):
  59.                 guard let nestedDict = self[key] as? [Key: Any] else {
  60.                     return nil
  61.                 }
  62.                 return nestedDict[path: remainingPath]
  63.             case .end:
  64.                 return self[key]
  65.             }
  66.         }
  67.         set {
  68.             let key = Key(string: keyPath.key)
  69.             switch keyPath {
  70.             case .end:
  71.                 if let value = newValue {
  72.                     self[key] = (value as! Value)
  73.                 } else {
  74.                     self[key] = nil
  75.                 }
  76.             case let .path(_, remainingPath):
  77.                 var nestedDict = self[key] as? [Key: Any] ?? [:]
  78.                 nestedDict[path: remainingPath] = newValue
  79.                 if nestedDict.isEmpty {
  80.                     self[key] = nil
  81.                 } else {
  82.                     self[key] = (nestedDict as! Value)
  83.                 }
  84.             }
  85.         }
  86.     }
  87. }
  88.  
  89. var dict: [String: Any] = [
  90.     "language": "de",
  91.     "translator": "Erika Fuchs",
  92.     "translations": [
  93.         "characters": [
  94.             "Scrooge McDuck": "Dagobert",
  95.             "Huey": "Tick",
  96.             "Dewey": "Trick",
  97.             "Louie": "Track",
  98.             "Gyro Gearloose": "Daniel Düsentrieb",
  99.         ],
  100.         "places": [
  101.             "Duckburg": "Entenhausen"
  102.         ]
  103.     ]
  104. ]
  105.  
  106. dict[path: "this.is.a.path"] = "this is a path"
  107. print(dict[path: "translations.places.Duckburg"])
  108. dict[path: "translations.places.Duckburg"] = nil
  109. print(dict)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top