Swift 中根據索引範圍建立新陣列


在 Swift 中,你可以使用 ArraySlice 型別建立一個數組。以下示例將展示如何使用 ArraySlice 型別。你也可以建立一個擴充套件來定義下標方法。

示例 1

在下面的示例中,我們建立了一個包含 0 到 9 值的數字陣列,然後建立了一個從 startIndex 到 endIndex(不包含 endIndex)的索引範圍。使用此範圍,我們可以生成原始陣列的 ArraySlice。最後,我們將使用 Array 初始化器將 ArraySlice 轉換為陣列並列印結果。

import Foundation
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let startIndex = 3 // inclusive
let endIndex = 8 // exclusive
let slice = numbers[startIndex..<endIndex] // return an ArraySlice<Int>
let newArray = Array(slice) // converts ArraySlice<Int> to [Int]
print("Original array: \(numbers)")
print("New array: \(newArray)")

輸出

Original array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
New array: [3, 4, 5, 6, 7]

請注意,startIndex 是包含的,而 endIndex 是不包含的。這意味著新陣列將包含從 startIndex 開始的原始陣列中的元素,但不包括 endIndex。

示例 2

假設你有一個 Student 物件陣列,其中每個學生都有姓名和年齡。假設你想要獲取一個包含 25 到 35 歲學生的新陣列。要獲取這些學生,可以使用索引範圍。

演算法

步驟 1 − 在此示例中,我們使用 firstIndex(where:) 方法查詢年齡大於或等於 25 的第一個學生的索引。我們使用 nil 合併運算子 ?? 來提供一個預設值 0,如果 firstIndex 方法返回 nil(即,如果沒有年齡為 25 或更大的學生)。

步驟 2 − 我們做同樣的事情來查詢年齡大於 35 的第一個學生的索引。如果不存在年齡超過 35 歲的學生,我們在這裡使用 student 陣列的 endIndex 屬性。

步驟 3 − 最後,我們透過使用我們計算的起始和結束索引切片原始學生的陣列,然後使用 Array 初始化器將生成的 ArraySlice 轉換為陣列來建立一個新陣列。

步驟 4 − 生成的 filteredStudents 陣列將只包含年齡在 25 到 35 歲之間的學生,順序與他們在原始學生陣列中出現的順序相同。

步驟 5 − 請記住,索引範圍是半開區間,這意味著年齡為 25 的學生將包含在新陣列中,但年齡為 35 的學生將不會包含(假設原始陣列中存在這樣的學生)。

程式碼如下

import Foundation
struct Student {
   let name: String
   let age: Int
}
let students = [
   Student(name: "Alice", age: 30),
   Student(name: "Bob", age: 25),
   Student(name: "Charlie", age: 35),
   Student(name: "Dave", age: 40),
   Student(name: "Eve", age: 20),
   Student(name: "Frainke", age: 33)
]
let startingIndex = students.firstIndex { $0.age >= 25 } ?? 0
let endingIndex = students.firstIndex { $0.age > 35 } ?? students.endIndex
let filteredStudents = Array(students[startingIndex..<endingIndex])
print("Original Student Names: - ")
students.forEach { student in
   print(student.name)
}
print("Filtered Student Names: - ")
filteredStudents.forEach { student in
   print(student.name)
}

輸出

Original Student Names: - 
Alice
Bob
Charlie
Dave
Eve
Frainke

Filtered Student Names: - 
Alice
Bob
Charlie

推薦方法

還有一種高效且安全的方法可以根據索引範圍建立新陣列。在這種方法中,你可以建立如下所示的擴充套件 −

示例

import Foundation
extension Array {
    
   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]
   }
}
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print("Original array: \(numbers)")
print(numbers[safe: 0..<1])
print(numbers[safe: 5..<100])
print(numbers[safe: -5..<50])
print(numbers[safe: 5, 10])

輸出

Original array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0]
[5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9]

結論

在 Swift 中,根據一組索引建立一個新陣列是很常見的做法,根據你的需求,你可以採取各種方法。

要根據部分開區間索引構造一個新陣列,請使用帶有原始陣列切片的 Array 初始化器。雖然這是一種清晰簡潔的方法,但是你必須手動計算起始和結束索引。

為了提供更實用的建立陣列切片的方法,你可以選擇對 Array 使用擴充套件。使用這種更靈活的方法,你可以使用包含式、排除式或部分開區間索引建立切片。

更新於:2023年4月11日

874 次瀏覽

啟動你的職業生涯

完成課程獲得認證

開始學習
廣告
© . All rights reserved.