programing

Index Range Swift의 새로운 어레이

showcode 2023. 4. 15. 09:42
반응형

Index Range Swift의 새로운 어레이

어떻게 하면 이런 일을 할 수 있을까요?배열에서 처음 n개의 요소를 가져옵니다.

newNumbers = numbers[0..n]

현재 다음 오류가 발생하고 있습니다.

error: could not find an overload for 'subscript' that accepts the supplied arguments

편집:

이것이 제가 하고 있는 기능입니다.

func aFunction(numbers: Array<Int>, position: Int) -> Array<Int> {
    var newNumbers = numbers[0...position]
    return newNumbers
}

이것으로 충분합니다.

var test = [1, 2, 3]
var n = 2
var test2 = test[0..<n]

어레이를 선언하는 방법에 문제가 있을 수 있습니다.

편집:

기능을 고치기 위해서는 캐스트를 해야 합니다.Slice어레이:

func aFunction(numbers: Array<Int>, position: Int) -> Array<Int> {
    var newNumbers = Array(numbers[0..<position])
    return newNumbers
}

// test
aFunction([1, 2, 3], 2) // returns [1, 2]

#1. 사용방법Array범위가 있는 첨자

Swift 5에서는 글을 쓸 때...

let newNumbers = numbers[0...position]

newNumbers타입이 아니다Array<Int>단, 종류입니다.ArraySlice<Int>왜냐하면...Array가 반환하는 것은ArraySlice<Element>Apple에 의하면, 대규모 어레이의 스토리지에 대한 뷰를 제공하고 있습니다.

게다가, 스위프트는 또한Arrayinitializer라는 이름의 이니셜라이저로 새로운 어레이를 생성할 수 있습니다.sequence(포함)ArraySlice).

이 때문에, 다음과 같이 사용할 수 있습니다.subscript(_:​)와 함께init(_:​)배열의 첫 번째 n개의 요소에서 새 배열을 가져오려면 다음 절차를 수행합니다.

let array = Array(10...14) // [10, 11, 12, 13, 14]
let arraySlice = array[0..<3] // using Range
//let arraySlice = array[0...2] // using ClosedRange also works
//let arraySlice = array[..<3] // using PartialRangeUpTo also works
//let arraySlice = array[...2] // using PartialRangeThrough also works
let newArray = Array(arraySlice)
print(newArray) // prints [10, 11, 12]

#2. 사용방법Arrayprefix(_:)방법

Swift는 다음을 준수하는 유형을 위한 메서드를 제공합니다.Collection프로토콜(포함)Array).prefix(_:)에는 다음 선언이 있습니다.

func prefix(_ maxLength: Int) -> ArraySlice<Element>

첫 번째 요소를 포함하는 최대 maxLength 길이의 후속 요소를 반환합니다.

Apple은 다음과 같이 기술하고 있습니다.

최대 길이가 컬렉션의 요소 수를 초과하면 결과에는 컬렉션의 모든 요소가 포함됩니다.

따라서 이전 예시와 달리 다음 코드를 사용하여 다른 배열의 첫 번째 요소에서 새 배열을 만들 수 있습니다.

let array = Array(10...14) // [10, 11, 12, 13, 14]
let arraySlice = array.prefix(3)
let newArray = Array(arraySlice)
print(newArray) // prints [10, 11, 12]

첨자

extension Array where Element : Equatable {
  public subscript(safe bounds: Range<Int>) -> ArraySlice<Element> {
    if bounds.lowerBound > count { return [] }
    let lower = Swift.max(0, bounds.lowerBound)
    let upper = Swift.max(0, Swift.min(count, bounds.upperBound))
    return self[lower..<upper]
  }
  
  public subscript(safe lower: Int?, _ upper: Int?) -> ArraySlice<Element> {
    let lower = lower ?? 0
    let upper = upper ?? count
    if lower > upper { return [] }
    return self[safe: lower..<upper]
  }
}

지정된 제한 범위로 클램프된 이 범위의 복사본을 반환합니다.

var arr = [1, 2, 3]
    
arr[safe: 0..<1]    // returns [1]  assert(arr[safe: 0..<1] == [1])
arr[safe: 2..<100]  // returns [3]  assert(arr[safe: 2..<100] == [3])
arr[safe: -100..<0] // returns []   assert(arr[safe: -100..<0] == [])

arr[safe: 0, 1]     // returns [1]  assert(arr[safe: 0, 1] == [1])
arr[safe: 2, 100]   // returns [3]  assert(arr[safe: 2, 100] == [3])
arr[safe: -100, 0]  // returns []   assert(arr[safe: -100, 0] == [])

어레이의 기능 방법:

   array.enumerated().filter { $0.offset < limit }.map { $0.element }

범위:

 array.enumerated().filter { $0.offset >= minLimit && $0.offset < maxLimit }.map { $0.element }

이 방법의 장점은 이러한 구현이 안전하다는 것입니다.

다른 변종 1개:extension및 인수명range

이 확장자는Range그리고.ClosedRange

extension Array {

    subscript (range r: Range<Int>) -> Array {
        return Array(self[r])
    }


    subscript (range r: ClosedRange<Int>) -> Array {
        return Array(self[r])
    }
}

테스트:

func testArraySubscriptRange() {
    //given
    let arr = ["1", "2", "3"]

    //when
    let result = arr[range: 1..<arr.count] as Array

    //then
    XCTAssertEqual(["2", "3"], result)
}

func testArraySubscriptClosedRange() {
    //given
    let arr = ["1", "2", "3"]

    //when
    let result = arr[range: 1...arr.count - 1] as Array

    //then
    XCTAssertEqual(["2", "3"], result)
}

언급URL : https://stackoverflow.com/questions/24034398/new-array-from-index-range-swift

반응형