Array Baru dari Index Range Swift

122

Bagaimana saya bisa melakukan sesuatu seperti ini? Ambil n elemen pertama dari sebuah array:

newNumbers = numbers[0..n]

Saat ini mendapatkan kesalahan berikut:

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

EDIT:

Inilah fungsi yang saya kerjakan.

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

Jawaban:

181

Ini bekerja untuk saya:

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

Masalah Anda mungkin dengan bagaimana Anda mendeklarasikan array Anda untuk memulai.

EDIT:

Untuk memperbaiki fungsi Anda, Anda harus mentransmisikan Sliceke array:

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]
Cezary Wojcik
sumber
Saya telah menambahkan lebih banyak konteks ke pertanyaan saya, saya sedang mengerjakan sebuah fungsi. Ini bekerja secara independen, tetapi tidak di dalam fungsi.
Charlie Egan
1
Menyenangkan! Cheers - itu berhasil. Saya akan menerima jawabannya jika memungkinkan.
Charlie Egan
23
Titik bertele-tele, tapi ini tidak benar-benar pengecoran yang Sliceke Array, melainkan menciptakan sebuah array baru dari sepotong. Seorang pemeran akan menggunakan asoperator: numbers as Arrayyang akan menghasilkan kesalahan.
jb
Bahasanya telah berubah, menggunakan tiga elipsis dan bukan dua developer.apple.com/library/ios/documentation/General/Reference/…
Daniel Galasko
2
Kedua titik itu ..berubah menjadi ..<; tiga titik (elipsis) tetap sama. Terima kasih atas pengingatnya; Saya memperbarui jawabannya.
Cezary Wojcik
100

# 1. Menggunakan Arraysubskrip dengan rentang

Dengan Swift 5, saat Anda menulis…

let newNumbers = numbers[0...position]

newNumbersBukanlah tipe Array<Int>tapi tipe ArraySlice<Int>. Itu karena Array's subscript(_:​)kembali sebuah ArraySlice<Element>itu, menurut Apple, hadiah pandangan ke penyimpanan beberapa array yang lebih besar.

Selain itu Swift juga menyediakan Arraysebuah penginisialisasi bernama init(_:​)yang memungkinkan kita membuat array baru dari a sequence(termasuk ArraySlice).

Oleh karena itu, Anda dapat menggunakan subscript(_:​)with init(_:​)untuk mendapatkan array baru dari n elemen pertama dari sebuah array:

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. Menggunakan Array's prefix(_:)metode

Swift menyediakan prefix(_:)metode untuk tipe yang sesuai dengan Collectionprotokol (termasuk Array). prefix(_:)memiliki deklarasi berikut:

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

Mengembalikan sebuah urutan, hingga panjang maxLength, yang berisi elemen awal.

Apple juga menyatakan:

Jika panjang maksimum melebihi jumlah elemen dalam koleksi, hasilnya berisi semua elemen dalam koleksi.

Oleh karena itu, sebagai alternatif dari contoh sebelumnya, Anda dapat menggunakan kode berikut untuk membuat array baru dari elemen pertama dari array lain:

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]
Imanou Petit
sumber
7
func subArray<T>(array: [T], range: NSRange) -> [T] {
  if range.location > array.count {
    return []
  }
  return Array(array[range.location..<min(range.length, array.count)])
}
Phil
sumber
tolong tambahkan penjelasan untuk jawabannya juga.
Naman
Jawaban yang sangat bagus. Apa yang pada dasarnya dilakukannya adalah mentransmisikan ArraySlice <T> ke Array. Secara pribadi saya tidak akan menyertakan banyak pernyataan. Karena saya biasanya ingin slice gagal jika saya memberikan rentang palsu, dll.
eonist
0

Satu lagi varian menggunakan extensiondan nama argumenrange

Ekstensi ini menggunakan RangedanClosedRange

extension Array {

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


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

Tes:

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)
}
yoAlex5
sumber
0

Array cara fungsional:

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

berkisar:

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

Keuntungan dari metode ini adalah penerapannya aman.

Vyacheslav
sumber