1

I'm working on a macOS Swift-app where I need to perform folder/file traversal. In this specific instance, I need to remove the first part of a file path...i.e., if a file has the path of MyFolder/MyItem, I need it to just read as MyItem for display purposes.

Based off the responses in this answer, I wrote the following code:

if fileString.hasPrefix("/") {
    fileString.remove(at: fileString.startIndex)
    print(fileString)
}

...where I remove any part of the fileString before and including "/".

However, this doesn't seem to work in practice....MyFile/MyItem doesn't get changed to MyItem, it remains as MyFile/MyItem.

narner
  • 2,908
  • 3
  • 26
  • 63
  • 1
    The code you posted would change `/MyFile/MyItem` to `MyFile/MyItem`. Why do you expect your code to remove a `/` in the middle? – rmaddy Jan 04 '18 at 19:50
  • Swift doesn't modify your string, I believe it creates a new one. Try var s = (your line) and then see what s has – Stephen J Jan 04 '18 at 19:52
  • @rmaddy I see, makes sense. How would I then remove "/" and whatever is before it? – narner Jan 04 '18 at 20:12
  • use the substring after getting the index of the /. Just remember Swift does copy-on-change – Stephen J Jan 04 '18 at 20:26
  • Actually, the `remove(at:)` method is a mutating function: it _will_ modify the value of fileString in-place, without requiring you to re-assign the variable. In fact, the return value of that method is _not_ the modified string, but the character that was removed from the string. Copy-on-write is an important concept in Swift but it's not really relevant to this question. – Mike Mertsock Jan 04 '18 at 22:20

1 Answers1

2

You can locate the first (or last) slash character and remove everything from the beginning of the string up to and including that separator, for example:

var fileString = "My Volume/My Folder/My Item"
if let r = fileString.range(of: "/", options: .backwards) {
    fileString.removeSubrange(..<r.upperBound)
}
print(fileString) // My Item

But if your intention is to extract the file name (last path component) for display then there is a dedicated method for that purpose:

let fileString = "My Volume/My Folder/My Item"
let displayName = FileManager.default.displayName(atPath: fileString)
print(displayName) // My Item

Another method is

let fileString = "My Volume/My Folder/My Item"
let baseName = URL(fileURLWithPath: fileString).lastPathComponent
print(baseName) // My Item

which is similar to the previous one, but does not localize the file name.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382