Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
String truncate extension for Swift 4
extension String {
/*
Truncates the string to the specified length number of characters and appends an optional trailing string if longer.
- Parameter length: Desired maximum lengths of a string
- Parameter trailing: A 'String' that will be appended after the truncation.
- Returns: 'String' object.
*/
func trunc(length: Int, trailing: String = "") -> String {
return (self.count > length) ? self.prefix(length) + trailing : self
}
}
// Swift 4.0 Example
let str = "I might be just a little bit too long".truncate(10) // "I might be…"
@akarca
Copy link

akarca commented Nov 28, 2017

import Foundation

extension String {
    enum TruncationPosition {
        case head
        case middle
        case tail
    }

    func truncated(limit: Int, position: TruncationPosition = .tail, leader: String = "...") -> String {
        guard self.count > limit else { return self }

        switch position {
        case .head:
            return leader + self.suffix(limit)
        case .middle:
            let headCharactersCount = Int(ceil(Float(limit - leader.count) / 2.0))

            let tailCharactersCount = Int(floor(Float(limit - leader.count) / 2.0))
            
            return "\(self.prefix(headCharactersCount))\(leader)\(self.suffix(tailCharactersCount))"
        case .tail:
            return self.prefix(limit) + leader
        }
    }
}

@keithmichelson
Copy link

keithmichelson commented Dec 10, 2017

Very helpful, thanks.

.trunc(10)

@SalvatoreAD
Copy link

SalvatoreAD commented Feb 2, 2018

Is it possible to modify it so that the last word is not cut?

@kdeda
Copy link

kdeda commented Nov 5, 2018

I am getting bit by this, the truncated string has count = to length + the trailing.count. HOWEVER lengthOfBytes(using: .utf8) will be more than that, so it fails to insert into a varchar[length]
my string is utf-16

@hardikdarji
Copy link

hardikdarji commented Nov 13, 2018

nice solution

@namnd
Copy link

namnd commented May 28, 2019

@salva
Something like this

func trunc(length: Int, trailing: String = "…") -> String {
    if (self.count <= length) {
      return self
    }
    var truncated = self.prefix(length)
    while truncated.last != " " {
      truncated = truncated.dropLast()
    }
    return truncated + trailing
  }

@salva
Copy link

salva commented May 28, 2019

@namnd, wrong Salva!
You probably meant @SalvatoreAD

@siqiz7
Copy link

siqiz7 commented Aug 6, 2019

Thanks a lot!

@Kedar-27
Copy link

Kedar-27 commented Jun 17, 2020

Thanks a lot

@dkk
Copy link

dkk commented Apr 6, 2021

Nice Gist, I would only add taking into account the trailing for the length of the string (I also updated the function signature to work with your example):

extension String {
    func truncate(_ length: Int, trailing: String = "…") -> String {        
        (self.count > length) ? self.prefix(max(0, length - trailing.count)) + trailing : self
    }
}

Using your example, let str = "I might be just a little bit too long".truncate(10) would now return a string with 10 characters (I might…), instead of 13 like before (I might be…).

@ppoh71
Copy link

ppoh71 commented Apr 23, 2021

@salva
Something like this

func trunc(length: Int, trailing: String = "…") -> String {
    if (self.count <= length) {
      return self
    }
    var truncated = self.prefix(length)
    while truncated.last != " " {
      truncated = truncated.dropLast()
    }
    return truncated + trailing
  }

Works, just needs a guard in case the string has no " " space

func trunc(length: Int, trailing: String = "…") -> String {
    if (self.count <= length) {
      return self
    }
    var truncated = self.prefix(length)
    while truncated.last != " " {

          guard truncated.count > length else {
            break
          }
      truncated = truncated.dropLast()
    }
    return truncated + trailing
  }
`

@salva
Copy link

salva commented Apr 23, 2021

You keep summoning me, so...

If the main use of trunc is to shorten strings that are too long for presentation purposes, it doesn't make sense to make the replacement when the substitution string is actually longer than the part that is being removed:

A better approach is to let the length argument mean the new length of the string, with trailing included:

var truncated = self.prefix(length - trailing.count)

Then you may like to consider the edge case where the length of trailing is bigger than length.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment