0

Is there any built-in solution that allows to substitute strings in a manner of NSExpression does (i.e. with a binding dictionary provided)?

So instead of:

let s = String(format: "%@ %@", arguments: ["foo", "bar"]) // "foo bar"

we have:

let s = String(format: "$foo $bar", ["foo": "hello", "bar": "world"]) // hello world

P.S. I'm aware of replaceOccurrences, I need NSExpression style substitution. Thanks!

rmaddy
  • 314,917
  • 42
  • 532
  • 579
m8labs
  • 3,671
  • 2
  • 30
  • 32
  • 2
    There's nothing built-in like that, but nothing prevents you from writing your own method that behaves like that. – matt Jan 27 '18 at 00:32

1 Answers1

1

As already mentioned by matt you would need to implement your own method. You can use a regex to match the ranges of all keys of your dictionary that starts with a dollar sign "\\$\\w+" and use the method "ranges(of:)" of this answer to replace the subranges of your string creating a custom initializer extending String:

extension String {
    init(format: String, _ dictionary: [String: String]) {
        var result = format
        for range in format.ranges(of: "\\$\\w+", options: .regularExpression).reversed() {
            result.replaceSubrange(range, with: dictionary[String(format[range].dropFirst())] ?? "")
        }
        self = result
    }
}

Playground testing:

let result = String(format: "$foo $bar", ["foo": "hello", "bar": "world"])
print(result)   // "hello world"
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Obviously the implementer can decide what is best but it might be a good idea to replace missing keys with something more obvious than the empty string. Perhaps the original key, including the `$` sign. This would make debugging a lot easier since it is much more noticeable. – rmaddy Jan 27 '18 at 01:23
  • @rmaddy I could also just force unwrap and make it crash. He can just add a default value `format[range]` if he wants to – Leo Dabus Jan 27 '18 at 01:24
  • @LeoDabus how fast is that? Looks pretty legit, but not suitable for UITableView I guess... – m8labs Jan 27 '18 at 01:28
  • It can't get faster than that – Leo Dabus Jan 27 '18 at 01:29