Programing

Swift에서 문자열에서 첫 번째 문자를 제거하는 가장 간결한 방법은 무엇입니까?

lottogame 2020. 8. 15. 09:42
반응형

Swift에서 문자열에서 첫 번째 문자를 제거하는 가장 간결한 방법은 무엇입니까?


문자열에서 첫 번째 문자를 삭제하고 싶습니다. 지금까지 제가 생각 해낸 가장 간결한 것은 다음과 같습니다.

display.text = display.text!.substringFromIndex(advance(display.text!.startIndex, 1))

Int유니 코드 때문에 문자열로 인덱싱 할 수 없다는 것을 알고 있지만이 솔루션은 매우 장황 해 보입니다. 내가 간과하는 또 다른 방법이 있습니까?


Swift 3을 사용 하는 경우이 답변의 두 번째 섹션을 무시할 수 있습니다. 좋은 소식은 이것이 실제로 다시 간결하다는 것입니다! String의 새로운 remove (at :) 메서드를 사용하기 만하면됩니다.

var myString = "Hello, World"
myString.remove(at: myString.startIndex)

myString // "ello, World"

나는 dropFirst()이것에 대한 전역 함수를 좋아합니다 .

let original = "Hello" // Hello
let sliced = dropFirst(original) // ello

짧고 명확하며 Sliceable 프로토콜을 준수하는 모든 것에 대해 작동합니다.

Swift 2 를 사용하는 경우이 답변이 변경되었습니다. dropFirst는 여전히 사용할 수 있지만 strings characters속성 에서 첫 번째 문자를 삭제 한 다음 결과를 다시 String으로 변환 하지 않으면 사용할 수 없습니다 . dropFirst는 또한 함수가 아닌 메소드가되었습니다.

let original = "Hello" // Hello
let sliced = String(original.characters.dropFirst()) // ello

또 다른 대안은 접미사 함수를 사용하여 문자열의 UTF16View. 물론 나중에 다시 문자열로 변환해야합니다.

let original = "Hello" // Hello
let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // ello

이 모든 것은 내가 원래 제공 한 솔루션이 최신 버전의 Swift에서이 작업을 수행하는 가장 간결한 방법이 아닌 것으로 밝혀 졌다는 것입니다. removeAtIndex()짧고 직관적 인 솔루션을 찾고 있다면 @chris의 솔루션을 사용 하는 것이 좋습니다 .

var original = "Hello" // Hello
let removedChar = original.removeAtIndex(original.startIndex)

original // ello

아래 주석에서 @vacawama가 지적했듯이 원래 문자열을 수정하지 않는 또 다른 옵션은 substringFromIndex를 사용하는 것입니다.

let original = "Hello" // Hello
let substring = original.substringFromIndex(advance(original.startIndex, 1)) // ello

또는 문자열의 시작과 끝에서 문자를 삭제하려는 경우 substringWithRange를 사용할 수 있습니다. 때 상태에 대해 경계하십시오 startIndex + n > endIndex - m.

let original = "Hello" // Hello

let newStartIndex = advance(original.startIndex, 1)
let newEndIndex = advance(original.endIndex, -1)

let substring = original.substringWithRange(newStartIndex..<newEndIndex) // ell

마지막 줄은 아래 첨자 표기법을 사용하여 작성할 수도 있습니다.

let substring = original[newStartIndex..<newEndIndex]

Swift 4 업데이트

Swift 4에서는 다시 String준수 Collection하므로 문자열의 시작과 끝 을 사용 dropFirst하고 dropLast트리밍 할 수 있습니다. 결과는 유형 Substring이므로 String생성자에 전달하여 다음 을 반환해야합니다 String.

let str = "hello"
let result1 = String(str.dropFirst())    // "ello"
let result2 = String(str.dropLast())     // "hell"

dropFirst()그리고 dropLast()또한을 Int드롭 문자의 수를 지정합니다 :

let result3 = String(str.dropLast(3))    // "he"
let result4 = String(str.dropFirst(4))   // "o"

삭제할 문자를 문자열보다 더 많이 지정하면 결과는 빈 문자열 ( "")이됩니다.

let result5 = String(str.dropFirst(10))  // ""

Swift 3 업데이트

첫 번째 문자 만 제거하고 원래 문자열을 변경하려면 @MickMacCallum의 답변을 참조하십시오. 프로세스에서 새 문자열을 생성하려면 substring(from:). 확장과 함께합니다 String, 당신의 추함을 숨길 수 substring(from:)substring(to:)시작과 끝을 잘라 유용한 추가를 만들 String:

extension String {
    func chopPrefix(_ count: Int = 1) -> String {
        return substring(from: index(startIndex, offsetBy: count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
        return substring(to: index(endIndex, offsetBy: -count))
    }
}

"hello".chopPrefix()    // "ello"
"hello".chopPrefix(3)   // "lo"

"hello".chopSuffix()    // "hell"
"hello".chopSuffix(3)   // "he"

마찬가지로 dropFirstdropLast그들 앞에,이 함수는 문자열에서 사용할 수있는 충분한 문자가없는 경우 충돌합니다. 제대로 사용하려면 발신자에게 책임이 있습니다. 이것은 유효한 설계 결정입니다. 선택 사항을 반환하도록 작성하면 호출자가 풀어야합니다.


스위프트 2.x

에 아아 스위프트 2 , dropFirstdropLast(이전의 가장 좋은 방법은) 그들이 예전처럼 편리하지 않습니다. 확장명을 사용하면 String의 추악함을 숨길 수 있습니다 .substringFromIndexsubstringToIndex

extension String {
    func chopPrefix(count: Int = 1) -> String {
         return self.substringFromIndex(advance(self.startIndex, count))
    }

    func chopSuffix(count: Int = 1) -> String {
        return self.substringToIndex(advance(self.endIndex, -count))
    }
}

"hello".chopPrefix()    // "ello"
"hello".chopPrefix(3)   // "lo"

"hello".chopSuffix()    // "hell"
"hello".chopSuffix(3)   // "he"

마찬가지로 dropFirstdropLast그들 앞에,이 함수는 문자열에서 사용할 수있는 충분한 문자가없는 경우 충돌합니다. 제대로 사용하려면 발신자에게 책임이 있습니다. 이것은 유효한 설계 결정입니다. 선택 사항을 반환하도록 작성하면 호출자가 풀어야합니다.


에서 스위프트 1.2 , 당신은 전화를해야합니다 chopPrefix다음과 같이 :

"hello".chopPrefix(count: 3)  // "lo"

또는 _함수 정의에 밑줄 추가 하여 매개 변수 이름을 억제 할 수 있습니다 .

extension String {
    func chopPrefix(_ count: Int = 1) -> String {
         return self.substringFromIndex(advance(self.startIndex, count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
        return self.substringToIndex(advance(self.endIndex, -count))
    }
}

스위프트 2.2

'advance' is unavailable: call the 'advancedBy(n)' method on the index

    func chopPrefix(count: Int = 1) -> String {
        return self.substringFromIndex(self.startIndex.advancedBy(count))
    }

    func chopSuffix(count: Int = 1) -> String {
        return self.substringFromIndex(self.endIndex.advancedBy(count))
    }

Swift 3.0

    func chopPrefix(_ count: Int = 1) -> String {
        return self.substring(from: self.characters.index(self.startIndex, offsetBy: count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
       return self.substring(to: self.characters.index(self.endIndex, offsetBy: -count))
    }

Swift 3.2

A view of the string's contents as a collection of characters.

@available(swift, deprecated: 3.2, message: "Please use String or Substring directly")
public var characters: String.CharacterView
func chopPrefix(_ count: Int = 1) -> String {
    if count >= 0 && count <= self.count {
        return self.substring(from: String.Index(encodedOffset: count))
    }
    return ""
}

func chopSuffix(_ count: Int = 1) -> String {
    if count >= 0 && count <= self.count {
        return self.substring(to: String.Index(encodedOffset: self.count - count))
    }
    return ""
}

Swift 4

extension String {

    func chopPrefix(_ count: Int = 1) -> String {
        if count >= 0 && count <= self.count {
            let indexStartOfText = self.index(self.startIndex, offsetBy: count)
            return String(self[indexStartOfText...])
        }
        return ""
    }

    func chopSuffix(_ count: Int = 1) -> String {
        if count >= 0 && count <= self.count {
            let indexEndOfText = self.index(self.endIndex, offsetBy: -count)
            return String(self[..<indexEndOfText])
        }
        return ""
    }
}

In Swift 2, do this:

let cleanedString = String(theString.characters.dropFirst())

I recommend https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html to get an understanding of Swift strings.


Depends on what what you want the end result to be (mutating vs nonmutating).

As of Swift 4.1:

Mutating:

var str = "hello"
str.removeFirst() // changes str 

Nonmutating:

let str = "hello"
let strSlice = str.dropFirst() // makes a slice without the first letter
let str2 = String(strSlice)

Notes:

  • I put an extra step in the nonmutating example for clarity. Subjectively, combining the last two steps would be more succinct.
  • The naming of dropFirst seems a bit odd to me because if I am understanding the Swift API Design Guidelines correctly, dropFirst should really be something like dropingFirst because it is nonmutating. Just a thought :).

What about this?

s.removeAtIndex(s.startIndex)

This of course assumes that your string is mutable. It returns the character which has been removed, but alters the original string.


The previous answers are pretty good, but as of today, I think this may be the most succinct way to remove the first character from a string in Swift 4:

var line: String = "This is a string..."
var char: Character? = nil

char = line.removeFirst()

print("char = \(char)")  // char = T
print("line = \(line)")  // line = his is a string ...

I know of nothing more succinct out of the box, but you could easily implement prefix ++, e.g.,

public prefix func ++ <I: ForwardIndexType>(index: I) -> I {
    return advance(index, 1)
}

After which you can use it to your heart's content very succinctly:

str.substringFromIndex(++str.startIndex)

In Swift 2 use this String extension:

extension String
{
    func substringFromIndex(index: Int) -> String
    {
        if (index < 0 || index > self.characters.count)
        {
            print("index \(index) out of bounds")
            return ""
        }
        return self.substringFromIndex(self.startIndex.advancedBy(index))
    }
}

display.text = display.text!.substringFromIndex(1)

"en_US,fr_CA,es_US".chopSuffix(5).chopPrefix(5) // ",fr_CA,"

extension String {
    func chopPrefix(count: Int = 1) -> String {
        return self.substringFromIndex(self.startIndex.advancedBy(count))
    }

    func chopSuffix(count: Int = 1) -> String {
        return self.substringToIndex(self.endIndex.advancedBy(-count))
    }
}

To remove first character from string

let choppedString = String(txtField.text!.characters.dropFirst())

Here is a Swift4 crash save version of the chopPrefix extension, leaving chopSuffix to the community ...

extension String {
    func chopPrefix(_ count: Int = 1) -> String {
        return count>self.count ? self : String(self[index(self.startIndex, offsetBy: count)...])
    }
 }

Swift3

extension String {
    func chopPrefix(_ count: UInt = 1) -> String {
        return substring(from: characters.index(startIndex, offsetBy: Int(count)))
    }

    func chopSuffix(_ count: UInt = 1) -> String {
        return substring(to: characters.index(endIndex, offsetBy: -Int(count)))
    }
}

class StringChopTests: XCTestCase {
    func testPrefix() {
        XCTAssertEqual("original".chopPrefix(0), "original")
        XCTAssertEqual("Xfile".chopPrefix(), "file")
        XCTAssertEqual("filename.jpg".chopPrefix(4), "name.jpg")
    }

    func testSuffix() {
        XCTAssertEqual("original".chopSuffix(0), "original")
        XCTAssertEqual("fileX".chopSuffix(), "file")
        XCTAssertEqual("filename.jpg".chopSuffix(4), "filename")
    }
}

참고URL : https://stackoverflow.com/questions/28445917/what-is-the-most-succinct-way-to-remove-the-first-character-from-a-string-in-swi

반응형