ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift - Array
    Programming/Swift 2021. 8. 30. 13:50

     

     

    오늘은 Array(배열)에 대해서 공부해보겠습니다.

    배열은 가장 많이 사용하는 collection 중 하나이므로 꼭 알아두고 가야 하는 자료형입니다.

     


    Array (배열)

     

    Array는 정렬되어 있고 random-access가 가능한 Collection입니다.

    핵심은 정렬이 되어있다는 것 그리고 index를 이용하여 각 element에 접근이 가능하다는 점입니다.

     

    그럼 array에 대해서 CRUD(Create, Read, Update, Delete) 순으로 알아보겠습니다.

     


    Create

    Array를 생성하는 법을 먼저 공부해 보겠습니다.

     

     

     

    타입이 한가지가 아니면 에러가 발생합니다.

    배열을 생성하는 가장 쉬운 방법은 Array literal을 이용하는 방법입니다.

    Array literal의 포인트는 [] (Square bracket)입니다.

    [] 안에 원하는 데이터를 , (comma)로 나열하면 됩니다.

    단, 주의할 점은 모두 같은 Type이어야 합니다. 

     

    그렇다면 numberArray의 Type은 무엇일까요???

    numberArray의 Type은 [Int]입니다.

     

     

     

     

    numberArray의 타입은 Element를 보고 타입 추론을 하게 됩니다.

    위에서는 [Int] 타입이라고 했는데 출력 결과는 Array<Int> 타입이라고 나왔습니다.

    둘은 다른 타입일까요?? 아닙니다.

    Array<Int>는 정식 문법이고 [Int]는 단축 문법입니다.

    표현방식이 다른것은 이후에 제네릭에 대해서 공부하면 이해하실 수 있습니다.

     

    그럼 이 두가지 타입을 이용하여 타입 지정으로 같은 배열을 만들어 보겠습니다.

     

     

     

     

    두 배열은 서로 같은 배열인 것을 확인할 수 있습니다.

     

     

    Emety Array (빈 배열)

     

    빈 배열을 생성할 때도 여러 문법이 존재합니다.

     

     

     

    이렇게 선언하면 타입 추론을 할 수 없으므로 에러가 발생합니다.

    배열은 element를 보고 타입을 추론해야 하는데 element가 없으므로 어떤 타입으로 추론해야 하는지 모르기 때문입니다.

     

     

     

     

    4개는 모두 빈 문자열을 생성하는 코드입니다.

    빈 문자열인지 확인하고 싶다면 .isEmpty 메서드를 사용합니다.

     


     

    Read

    Index (인덱스)

     

    배열은 순서대로 저장이되고 Collection이므로 index로 각 element에 접근이 가능하다고 설명했습니다.

    여기서 Index를 사용할때 주의할 점은 index는 0부터 시작하는 정수입니다. 1부터 시작하지 않습니다.

    그리고 index의 범위를 항상 주의하며 사용해야 합니다.

     

     

     

     

    잘못된 index를 전달하니 error가 발생한 것을 볼 수 있습니다.

     

    이를 방지하기 위해서 프로퍼티를 사용할 수 도 있습니다.

     

     

    first, last 프로퍼티는 collection의 처음, 끝 element를 리턴해줍니다.

    Element? 옵셔널을 리턴하므로 만약 존재하지 않는다면 에러가 발생하는 게 아니라 nil을 리턴합니다.


    Element의 개수,  검색

    대부분 유용한 기능들은 프로퍼티나 메서드로 구현이 되어있습니다.

     

     

     

    배열의 개수를 알고 싶다면 count 프로퍼티를 이용하면 됩니다.

     

    만약 배열에 특정 element가 존재하는지 알고 싶다면 contain(_:) 메서드를 사용하면 됩니다.

    존재한다면 true를 존재하지 않는다면 false를 리턴해줍니다.

     

    검색을 좀 더 구체적으로 하고 싶다면 클로저를 파라미터로 전달하는 contain(where:) 메서드를 이용하면 됩니다.

     


     

    Update

     

    Element를 추가하거나 변경하려면 배열이 var로 선언이 돼있어야 합니다.

     

     

     

     

    append(_:) 메서드는 배열 가장 뒤에 element를 추가시킵니다.

     

    insert(_:at:) 메서드는 배열 중간에 추가를 합니다.

    이때 오버헤드가 발생할 수 있으므로 꼭 필요한 경우에만 사용하고 추가를 하고 싶다면 append(_:)를 사용하는 것이 좋습니다.

    이유는 배열 중간에 element를 추가한다면 그 뒤에 있는 element들은 한 칸씩 이동해야하기 때문입니다.

     

    인덱스를 파라미터로 전달할 때는 항상 주의해야 합니다.

    잘못된 인덱스를 전달하면 오류가 발생합니다.

     

    여러 element를 추가하고 싶다면 append(contentsOf:) insert(contentsOf:at:) 메서드를 사용하면 됩니다.

     

    Element를 추가시키는 게 아니라 원래 있던 element를 변경하고 싶다면 다음 메서드와 서브스크립트를 사용합니다.

     

     

     

     

    replaceSubrange(_:with:) 메서드는 수정하고 싶은 범위와 변경할 배열을 전달하면 됩니다.

     

    그리고 메서드를 사용하지 않고 서브스크립트를 이용해서 배열을 수정할 수도 있습니다.

    주의할 점은 서브스크립트를 이용하여 범위를 변경하고 싶다면 한 가지를 전달하더라도 [] 배열의 형태로 전달을 해야 합니다.

     

     


    Delete

    마지막으로 삭제에 대해서 알아보겠습니다.

     

     

     

    가장 기본적인 remove(at:) 메서드를 먼저 보겠습니다.

     

     

    이 메서드는 해당 Index의 element를 삭제시킵니다.

    여기서 봐야 할 부분은 리턴 값이 있다는 점입니다.

    remove(at:) 메서드는 해당 element를 삭제하고 삭제된 element를 리턴해줍니다.

     

    removeFirst(), removeLast() 메서드는 배열의 제일 앞 또는 뒤 element를 제거하고 리턴해주는 메서드입니다.

    removeFirst(_:), removeLast(_:)와 같이 파라미터가 있는 메서드는 정수를 전달하면 앞 또는 뒤에서부터 정수까지 element를 삭제합니다. 리턴은 하지 않습니다.

    이때 파라미터는 0 보다는 커야 하고 배열의 개수보다는 작아야 합니다.

    만약 그렇지 않다면 에러가 발생합니다.

     

    지금까지 설명한 remove 메서드들은 인덱스가 잘못되거나 배열이 빈 배열이라면 에러가 발생하는 위험이 있습니다.

    removeLast()와 유사하지만 안전한 메서드도 존재합니다.

     

     

    popLast()는 옵셔널을 리턴합니다.

    그러므로 만약에 배열이 비어있다고 해도 에러가 발생하지 않고 nil을 리턴해줍니다.

    하지만 popFirst() 메서드는 존재하지 않습니다.

     

    배열을 모두 삭제하는 방법에는 두 가지가 있습니다.

    1. 배열에 [] 빈 배열을 저장하는 방법입니다. 
    2. removeAll(keepingCapacity:) 메서드를 사용하는 방법입니다.

     

    여기서 removeAll(keepingCapacity:) 메서드는 파라미터의 기본값은 false입니다.

    false일 때는 배열과 메모리 공간을 모두 삭제합니다.

    true일 때는배열을 모두 지우지만 메모리의 공간은 지우지 않습니다.

    그렇게 되면 나중에 해당 배열에 값을 저장할 때 메모리의 공간을 지우는 방법보다 더 빠르게 작동될 수 있습니다.

     

     


    Array의 확장 메커니즘

     

    Array 구조는 모두 생성될 때 contents 만큼의 크기를 메모리에 할당합니다.

    그렇기 때문에 만약 array에 element를 추가한다면 공간을 확장시켜야 합니다.

    Swift에서는 어떻게 확장을 할까요??

     

    메모리의 새로운 곳에 현재 데이터의 2배 크기의 공간을 만들고 elements를 복사한 뒤 새 공간에 할당합니다.

    1개의 데이터만 추가된다고 크기를 1만큼만 더 할당하는 게 아니라 두배 크기의 공간을 새로 할당하게 됩니다.

    이러한 메커니즘은 성능에 영향을 줄 수 있습니다.

     

    그래서 만약 elements가 얼마나 추가되는지 대략적으로 알고 있다면 element를 추가하기 전에 reserveCapacity(_:) 메서드를 호출하여   원하는 만큼만 공간을 확장하게 할 수 있습니다.

    하지만 reserveCapacity(_:) 메서드를 사용하는 것이 성능 향상을 보장하지는 않습니다.

    추가될 elements를 저장할 충분한 여유공간이 있어도 이 메서드를 호출하면 무조건 공간을 새로 할당하게 됩니다.

    그리고 성능상의 이유로 파라미터로 전달한 공간보다 더 큰 공간이 할당될 수도 있습니다.

     

     


     

    참고자료

     

    https://kxcoding.com

     

    여러분의 새로운 도전을 응원합니다 | KxCoding

    Mastering SwiftUI 더 적은 코드로, 더 멋진 UI 만들기

    kxcoding.com

     

     

    https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

     

    Collection Types — The Swift Programming Language (Swift 5.6)

    Collection Types Swift provides three primary collection types, known as arrays, sets, and dictionaries, for storing collections of values. Arrays are ordered collections of values. Sets are unordered collections of unique values. Dictionaries are unordere

    docs.swift.org

     

     

    https://developer.apple.com/documentation/swift/array

     

    Apple Developer Documentation

     

    developer.apple.com

     

     

     

    728x90

    'Programming > Swift' 카테고리의 다른 글

    Swift - Set  (0) 2021.10.14
    Swift - Dictionary  (0) 2021.10.08
    Swift - Foundation Collection & Swift Collection  (0) 2021.08.28
    Swift - Sequence와 Collection (Sequence와 Collection의 차이)  (2) 2021.08.11
    Swift - CharacterSet  (1) 2021.08.07
Designed by Tistory.