-
-
Save kristopherjohnson/1fc55e811d944a430289 to your computer and use it in GitHub Desktop.
/** | |
Supports creation of a String from pieces | |
*/ | |
public class StringBuilder { | |
private var stringValue: String | |
/** | |
Construct with initial String contents | |
:param: string Initial value; defaults to empty string | |
*/ | |
public init(string: String = "") { | |
self.stringValue = string | |
} | |
/** | |
Return the String object | |
:return: String | |
*/ | |
public func toString() -> String { | |
return stringValue | |
} | |
/** | |
Return the current length of the String object | |
*/ | |
public var length: Int { | |
return countElements(stringValue) | |
} | |
/** | |
Append a String to the object | |
:param: string String | |
:return: reference to this StringBuilder instance | |
*/ | |
public func append(string: String) -> StringBuilder { | |
stringValue += string | |
return self | |
} | |
/** | |
Append a Printable to the object | |
:param: value a value supporting the Printable protocol | |
:return: reference to this StringBuilder instance | |
*/ | |
public func append<T: Printable>(value: T) -> StringBuilder { | |
stringValue += value.description | |
return self | |
} | |
/** | |
Append a String and a newline to the object | |
:param: string String | |
:return: reference to this StringBuilder instance | |
*/ | |
public func appendLine(string: String) -> StringBuilder { | |
stringValue += string + "\n" | |
return self | |
} | |
/** | |
Append a Printable and a newline to the object | |
:param: value a value supporting the Printable protocol | |
:return: reference to this StringBuilder instance | |
*/ | |
public func appendLine<T: Printable>(value: T) -> StringBuilder { | |
stringValue += value.description + "\n" | |
return self | |
} | |
/** | |
Reset the object to an empty string | |
:return: reference to this StringBuilder instance | |
*/ | |
public func clear() -> StringBuilder { | |
stringValue = "" | |
return self | |
} | |
} | |
/** | |
Append a String to a StringBuilder using operator syntax | |
:param: lhs StringBuilder | |
:param: rhs String | |
*/ | |
public func += (lhs: StringBuilder, rhs: String) { | |
lhs.append(rhs) | |
} | |
/** | |
Append a Printable to a StringBuilder using operator syntax | |
:param: lhs Printable | |
:param: rhs String | |
*/ | |
public func += <T: Printable>(lhs: StringBuilder, rhs: T) { | |
lhs.append(rhs.description) | |
} | |
/** | |
Create a StringBuilder by concatenating the values of two StringBuilders | |
:param: lhs first StringBuilder | |
:param: rhs second StringBuilder | |
:result StringBuilder | |
*/ | |
public func +(lhs: StringBuilder, rhs: StringBuilder) -> StringBuilder { | |
return StringBuilder(string: lhs.toString() + rhs.toString()) | |
} | |
// Examples | |
let sb = StringBuilder() | |
sb.append(1).append("+").append(1).append("=").append(2) | |
sb.toString() | |
let sb2 = StringBuilder() | |
sb2 += "2+2" | |
sb2 += "=" | |
sb2 += "4" | |
sb2.toString() | |
let sbAdd = sb + sb2 | |
sbAdd.toString() |
I also don't understand why someone would use this class. Swift's String class already has a +=
operator and an appendContentsOf
methods to concatenate strings. I came here expecting a Swift implementation of Java's StringBuilder class which efficiently allows you to build up a string, but this is not it.
This class is apparently intended to be a replacement for Java.lang.StringBuilder (StringBuffer) class in Swift. It is handy if you ever need to port working Java code over to Swift, and you don't want to change the existing code structure for whatever reason. (e.g. You're working on a project that will target both iOS and Android.)
@quickthyme @lyahdav @idmean @kristopherjohnson
I'm considering implementing a StringBuilder version for Swift.
I wonder if it's necessary.
The reason I wonder to implement this is because I'm not sure about the run time comlxisty of the method 'joinWords':
func joinWords(words: [String]) -> String {
var sentence = ""
for w in words {
sentence += w
}
return sentence
}
If one each concatenating, a new copy of the string is created, and the two strings are copied over, character by character. The first iteration requires us to copy X characters. The second iteration requires copying 2X characters. The third iteration requires 3X, and so on. The total time therefore is O(X + 2X + 3X …… nX) this reduce to O(Xn^2).
And of course we can implement it with O(Xn) with StringBuilder.
I'v tried to find on the Apple docmentntion about the run time complexity of the + operation, but without success.
Thanks,
Guy
very helpful . Thanks
Since swift compiler likes to hang, when used with many string concated together, this is very useful to me. Many thanks
This whole class does not make any sense as long as it is build up on: stringValue += string
. Normally a StringBuilder is used (C#, Java) to provide a, performance- and memory-wise, better solution than a simple string concatination (which introduces a lot of overhead).
While this comment is extremely 'late to the table',
Thanks for building this class. I was unable to use the Printable protocol. However, there is a need for a StringBuilder class similar to the Java equivalent. Although some may have never been exposed to java, StringBuilder and other java classes serve as a good model to use for some missing pieces in Swift. And yes, I needed it to build up a Json string from many pieces, and it does help. The complier did complain when I did the old 'stringValue += string' This class does solve that problem. I am not sure what the Printable protocol is? requires a description func? Anyway, thank you for taking the time and then posting it for some of the more gracious of us to use.
This was written for a very early version of Swift. As noted in other comments, it is not needed with the current String interface. Just use += or interpolated strings.
…That said, I just encountered the first case where I needed a reference object to which I can send append
messages.
@GuyKahlon a bit late here, but I discovered that Swift's String class uses an exponential growth strategy that makes appending to a string a constant time operation when averaged over many appends. See here for the source. So this means that there's no need for a StringBuilder class in Swift as using += on a swift String is already doing the performant thing that Java's StringBuilder class is doing.
Why should I anyone use this class? That’s just overhead isn’t it?