Skip to content

Instantly share code, notes, and snippets.

@lilyball
Forked from russbishop/StringExtensions.swift
Created June 5, 2015 05:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lilyball/f6844e35755e6a04c8f2 to your computer and use it in GitHub Desktop.
Save lilyball/f6844e35755e6a04c8f2 to your computer and use it in GitHub Desktop.
public enum TruncateMode {
case Head, Middle, Tail
}
public extension String {
/// Truncates a string to a maximum length in grapheme clusters using the
/// specified mode. If `addEllipsis` is `true`, the resulting string
/// including the ellipsis will be no longer than `maxLength`.
func truncateToLength(maxLength: Int, mode: TruncateMode = .Tail, addEllipsis: Bool = false) -> String {
if maxLength <= 0 {
return ""
}
switch mode {
case .Head:
let start = advance(endIndex, -maxLength, startIndex)
if start == startIndex {
// no truncation necessary
return self
}
if addEllipsis {
return "…\(self[start.successor()..<endIndex])"
}
return self[start..<endIndex]
case .Middle:
let tailLength = maxLength / 2
let headLength = maxLength - tailLength
let headEnd = advance(startIndex, headLength, endIndex)
if headEnd == endIndex {
// no truncation necessary
return self
}
let tailStart = advance(endIndex, -tailLength, headEnd)
if tailStart == headEnd {
// no truncation necessary
return self
}
// always add the ellipsis for middle truncation
return "\(self[startIndex..<headEnd.predecessor()])…\(self[tailStart..<endIndex])"
case .Tail:
let end = advance(startIndex, maxLength, endIndex)
if end == endIndex {
// no truncation necessary
return self
}
if addEllipsis {
return "\(self[startIndex..<end.predecessor()])…"
}
return self[startIndex..<end]
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment