EunHee-Jeong/TIL

String

EunHee-Jeong opened this issue · 0 comments

기본 속성

  • C, C++, Java와는 다르게 index에 Int로 접근이 불가능하다 !

    • String은 값 타입이며, (= 참조가 아님), index 값으로 Int가 아닌 Index 라는 자료형이 따로 존재한다.

      이를 통해 문자열의 위치를 계산한다.

      • 예시

        let strSample = "abcdef"
        
        print(strSample.index(strSample.startIndex, offsetBy: 0)) // offsetBy: → startIndex로부터 떨어진 길이
        // Index(_rawBits: 1)
        
        print(strSample.index(strSample.startIndex, offsetBy: 1))
        // Index(_rawBits: 65793)
  • 여러 줄의 문자열을 그대로 사용하고 싶을 때 ⇒ """ 로 묶기

  • 문자열의 길이 확인 ⇒ count (Int 형으로 반환)

  • 빈 문자열 확인 ⇒ isEmpty (Bool 형으로 반환)

  • 초기화

    • 반복되는 문자열로 초기화 ⇒ init(repeating: String, count: Int)
    • 형식을 지정해서 초기화 ⇒ init(format: String, CVarArg...)

문자열 요소: Character

문자열 보간 (문자열 삽입): String Interpolations

  • 큰 따옴표 중간에 \( ) 를 사용하여 표현식이나 변수를 문자열로 바꾸어 넣는 것을 의미한다.
    • 객체, 계산식 등을 넣을 수 있다.

    • 예시

      let price = 2
      let number = 3
      let cookiePrice = "\(number) cookies: $\(price * number)."
      // cookiePrice == "3 cookies: $6."

문자열 결합: Combine Strings

  • append(), + 연산자를 이용한다.

문자열 비교: Comparing Strings

  • 비교 연산자 ==, <, > 등을 사용한다.
  • 표현식이 다르더라도, 결과값이 동일하다면 같은 문자열로 인정된다.
    • 예시

      let cafe1 = "Cafe\u{301}"
      let cafe2 = "Café"
      print(cafe1 == cafe2) // true

문자열 요소의 접근: Subscript

  • Subscript 란? → 번역하자면 첨자 !

    Sequence, Dictionary 와 같은 대괄호 [ ] 안에 특정 값을 넣어 원하는 값을 바로 찾아올 수 있는 기능을 말한다.

    • 정의는 아래와 같다.

      subscript(String.Index) -> Character
  • 문자열의 경우, Index 를 통해 해당 위치의 Character 값에 접근해야 한다.

  • 하지만 Swift에서 String은 Index로 Int를 사용할 수 없으므로 따로 구해줘야 한다.

    • Index를 구하는 메서드들
      • startIndex, endIndex, index(before: String.Index), index(after: String.Index), index(String.Index, offsetBy: String.IndexDistance), firstIndex(of: Character), lastIndex(of: Character)

      • Extension을 활용해 정리해두면 편하다 !

        extension String {
        	func getChar(at index: Int) -> Character {
        		return self[self.index(self.startIndex, offsetBy: index)]
        	}
        
        	subscript(_ index: Int) -> Character {
        		return self[self.index(self.startIndex, offsetBy: index)]
        	}
        }
        
        // 사용 예시
        let str = "aBcDeF"
        print(str.getChar(at: 3)) // D
        print(str[3]) // D

부분 문자열: Substring

  • 부분 문자열 역시 String.Index 형 범위로 변환하여 구하는데, 반환 값이 Substring 형 (= String 형이 아님)으로 나오기 때문에 단순 참조만 하는 경우 활용한다.

    • Substring → 원본 문자열을 저장하는 메모리를 그대로 사용

      (= 원본 메모리의 인스턴스를 참조)

      (= 활용해야 하는 경우, String 으로 형변환하여 사용해야 함)

  • Subscript 를 통해 접근 가능하며, 이 역시 Extension을 활용해 정리해두면 편하다.

extension String {
	subscript(_ range: Range<Int> -> String {
		let fromIndex = self.index(self.startIndex, offsetBy: range.startIndex)
		let toIndex = self.index(self.startIndex, offsetBy: range.endIndex)
		return String(self[fromIndex..<toIndex])
	}
}

// 사용 예시
let str = "aBcDeF"
print(str[0..<3]) // aBc

문자 포함

  • 특정 문자를 포함하는 지의 여부를 구하려면 contains(_:) 를 사용한다. Bool 형으로 반환된다.

문자열을 배열로 만들기: String to Array

  • 고차함수 map() → String을 Character들로 하나하나 쪼개어 배열로 만드는 함수
    • 정의

      func map<U>(transform: (T) -> U) -> Array<U>

배열을 문자열로 만들기: Array to String

  • 고차함수 joined(seperator: ), reduce(initial, combine) → 배열 내 요소들을 합쳐주는 함수

접두어, 접미어 확인

  • prefix(_:), suffix(_:)
    • Substring 형으로 반환된다.
  • hasPrefix(_:), hasSuffix(_:)
    • Bool 형으로 반환된다.

대소문자 변환

  • uppercased(), lowercased()
    • 기존 문자열을 변경하는 것이 아닌, 새로운 문자열을 생성하여 반환한다.
    • 영문이 아니더라도 컴파일 오류는 발생하지 않지만 영문만 먹힌다 . .

ASCII Code

  • Literal이란? 소스 코드를 컴파일 할 경우, 정의되어 있는 내용을 그대로 정확하게 해석할 수 있어야 하는 값 (ex: int x = 12에서의 12)

  • String Literal ⇒ Character들로 구성됨.

    • Character ⇒ asciiValue 라는 속성을 가짐
      • .asciiValueUInt8 Optional을 반환 ⇒ 언래핑하여 사용하기
  • 예시

    let str = "Hello안녕"
    for c in str {
        guard let ascii = c.asciiValue else {
            print("\(c) cannot convert to Ascii")
            continue
        }
        print("\(c) => \(ascii)")
    }
    
    // H => 72
    // e => 101
    // l => 108
    // l => 108
    // o => 111
    // 안 cannot convert to Ascii
    // 녕 cannot convert to Ascii

Unicode

  • 대부분의 문자와 언어를 표현할 수 있으며 (= 한글 포함), 다른 시스템에서도 사용 가능함

  • CharacterUnicode Scalar

    • 생성자에 Character를 넣어서 → Scalar 인스턴스를 생성

      • → Scalar 출력 ⇒ 해당하는 문자 출력
      • → value 출력 ⇒ 숫자 코드 (UInt32) 출력
    • 예시

      let alphabetToScalar = Unicode.Scalar("A")
      print(alphabetToScalar)        // A
      print(alphabetToScalar.value)  // 65
      
      let hanguelToScalar = Unicode.Scalar("")
      print(hanguelToScalar)     // 가
      print(hanguelToScalar.value)   // 44032
  • IntUnicode Scalar

    • 숫자 → Scalar 인스턴스 생성

    • 옵셔널로 반환되기 때문에, 사용하려면 언래핑 해줘야 한다는 점을 유의하자.

    • 예시

      if let intToScalar = Unicode.Scalar(65) {
      	print(intToScalar) // A
      	print(intToScalar.value) // 65
      }



정리

기존 문자열을 변경 → 삽입, 삭제, 치환

  • \(), append(), +, -, .asciiValue, Unicode.Scalar()

새로운 문자열을 생성하여 반환

  • map(), joined(seperator: ), reduce(initial, combine)
  • uppercased(), lowercased()

Substring으로 반환

  • prefix(), suffix()
  • split()
  • 한 마디로 얘들을 쓸 때는 map을 해주자 . . .

Extension

extension String {
	func getChar(at index: Int) -> Character {
		return self[self.index(self.startIndex, offsetBy: index)]
	}

	subscript(_ index: Int) -> Character {
		return self[self.index(self.startIndex, offsetBy: index)]
	}

	subscript(_ range: Range<Int> -> String {
		let fromIndex = self.index(self.startIndex, offsetBy: range.startIndex)
		let toIndex = self.index(self.startIndex, offsetBy: range.endIndex)
		return String(self[fromIndex..<toIndex])
	}
}