2016-09-24 58 views
2

我需要爲數千個文件分割文件路徑的一部分。所以我需要一個快速功能。我自己寫的,但它似乎運行速度很慢:Swift 3:快速文件路徑分離

// find string in "str", split at the position, delivers left and right side 

func revFindSplit_(str : String, searchString : String) -> (String, String) { 
    let strr = String(str.characters.reversed()) // reverse main string 
    let searchStringr = String(searchString.characters.reversed()) // reverse search string too 

    if let strrindex = strr.range(of: searchStringr) { // now we can search from back to front 

     let rangeOfS2 = strr.characters.startIndex..<strrindex.lowerBound // we got search result: part 1 (front) 
     let rangeOfS1 = strrindex.lowerBound..<strr.characters.endIndex // part 2 (back) 
     let S2 = String(strr[rangeOfS2].characters.reversed()) // put together and reverse again 
     let S1 = String(strr[rangeOfS1].characters.reversed()) 

     // here we have to remove search string 
     let S1M1 = String(S1.characters.prefix(S1.characters.count - searchString.characters.count)) 

     return (S1M1, S2) 
    } 
    else { 
     return (str, "") // without splitting 
    } 
} 

// split path of filename into all 3 part: directory name, filename without extension, extension (without dot) 
// in one call (faster than the 3 functions separatly) 
func splitFilename_(str: String) -> (directory: String, filenameOnly: String, ext: String) { 
    let url = NSURL(fileURLWithPath: str) 
    let path = url.path! 

    // split path and filename 
    let (directory, filenameExt) = revFindSplit_(str: path, searchString: "/") 
    // split filename in filenameOnly and extension 
    let (filenameOnly, ext) = revFindSplit_(str: filenameExt, searchString: ".") 

    return (directory, filenameOnly, ext) 
} 

有沒有什麼辦法可以大大提高速度? (可能使用庫函數)

+0

我懷疑你使用@vardian解決方案時有性能問題。但是如果真的不夠快,你需要一個'戲劇性'的加速,從字符串'import Glibc'或'import Darwin'中獲取UTF8,並使用C函數(比如'basename','strstr'等等。)。 – hnh

回答

2

您可以減少整個代碼:

func splitFilename(str: String) -> (directory: String, filenameOnly: String, ext: String) { 
    let url = URL(fileURLWithPath: str) 
    return (url.deletingLastPathComponent().path, url.deletingPathExtension().lastPathComponent, url.pathExtension) 
} 
+0

非常好。正是我所搜索的。因爲我現在開始(使用Swift 3.0),所以我想做對。 :-) 非常感謝你。 –

1

按現代CPU標準劃分數千個字符串並不是一項大任務。要讓英特爾CPU陷入困境,您需要數百萬美元。你確定這是你的應用程序的瓶頸嗎?

「過早的優化是所有罪惡的根源」 - 高德納

最後,你的代碼是史詩!你有沒有嘗試內置到NSString的路徑操作?

func splitFileName(str: String) -> (directory: String, fileName: String, extension: String) { 
    let path = str as NSString 
    let directory = path.deletingLastPathComponent 

    let fileNameWithExtension = path.lastPathComponent as NSString 
    let fileNameWithoutExtension = fileNameWithExtension.deletingPathExtension 
    let fileExtension = fileNameWithExtension.pathExtension 

    return (directory, fileNameWithoutExtension, fileExtension) 
} 
+0

Swift中'NSString'的內置路徑操作已過時。 'URL'是最好的。 – vadian

+0

'NSString'上的方法仍然存在,'NSString'不會很快消失 –

+1

是的,但** Swift(3)**中的最新類(實際上是結構體)是'String '和'URL「。有一個性能原因,爲什麼Apple放棄了Swift'String'中的路徑操作方法,以鼓勵開發人員使用URL相關的API。 – vadian