Pytanie New Array z Index Range Swift


Jak mogę zrobić coś takiego? Weź pierwsze n elementów z tablicy:

newNumbers = numbers[0..n]

Obecnie pojawia się następujący błąd:

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

EDYTOWAĆ:

Oto funkcja, w której pracuję.

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

76
2018-06-04 09:58


pochodzenie




Odpowiedzi:


To działa dla mnie:

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

Problem może dotyczyć sposobu, w jaki deklarujesz swoją tablicę.

EDYTOWAĆ:

Aby naprawić swoją funkcję, musisz rzucić swoją Slice do tablicy:

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]

122
2018-06-04 10:01



Dodałem trochę więcej kontekstu do mojego pytania, pracuję wewnątrz funkcji. Działa to niezależnie, ale nie w funkcji. - Charlie Egan
Zaktualizowałem moją odpowiedź. - Cezary Wojcik
Śliczny! Pozdrawiam - to działa. Przyjmuję odpowiedź, kiedy mi pozwala. - Charlie Egan
Pedantyczny punkt, ale tak naprawdę nie jest odlew  Slice do Array, ale raczej tworzenie nowej tablicy z plasterka. Gips użyłby as operator: numbers as Array co spowodowałoby błąd. - Jamie Bullock
Dwie kropki.. zmienić na ..<; trzy kropki (elipsa) pozostały takie same. Dzięki za przypomnienie; Zaktualizowałem odpowiedź. - Cezary Wojcik


Z Swift 4, kiedy piszesz:

let newNumbers = numbers[0...position]

newNumbers nie jest typu Array<Int> ale jest typu ArraySlice<Int>. To jest ponieważ Array„s subscript(_:​) zwraca wartość ArraySlice<Element> to, według Apple, przedstawia widok na przechowywanie większej tablicy.

Poza tym Swift zapewnia również init(_:​) inicjator dla Array co pozwala nam utworzyć nową tablicę z a sequence (włącznie z ArraySlice).

Dlatego możesz użyć jednego z czterech poniższych sposobów, aby uzyskać nową tablicę pierwszego n elementy tablicy.


# 1. Za pomocą Array indeks dolny z zakresem

Możesz użyć Array indeks dolny z CountableRange, CountableClosedRange, PartialRangeUpTo lub partialRangeThrough w celu uzyskania podciągu pierwszych elementów tablicy.

Stosowanie: 

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

# 2. Za pomocą Array„s prefix(_:) metoda

Swift zapewnia prefix(_:) metoda dla typów zgodnych z Collection protokół (w tym Array). prefix(_:) ma następującą deklarację:

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

Zwraca podciąg, do maksymalnej długości, zawierający początkowe elementy.

Apple również stwierdza:

Jeśli maksymalna długość przekracza liczbę elementów w kolekcji, wynik zawiera wszystkie elementy w kolekcji.

Stosowanie: 

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]

# 3. Tworzenie niestandardowej funkcji globalnej

Poniższy kod do gry pokazuje ho, aby utworzyć globalną funkcję, która zwraca pierwszą n elementy Array:

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

let array = Array(10...14) // [10, 11, 12, 13, 14]
let newArray = aFunction(numbers: array, position: 3)
print(newArray) // prints [10, 11, 12]

# 4. Tworzenie Array niestandardowa metoda rozszerzenia

Poniższy kod do gry pokazuje ho, aby utworzyć Array niestandardowa metoda rozszerzenia, która zwraca pierwszą n elementy Array:

extension Array {

    func getFirstElements(upTo position: Int) -> Array<Element> {
        let arraySlice = self[0 ..< position]
        return Array(arraySlice)
    }

}

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

64
2017-12-15 22:43





func subArray<T>(array: [T], range: NSRange) -> [T] {
  if range.location > array.count {
    return []
  }
  return Array(array[range.location..<min(range.length, array.count)])
}

4
2018-06-01 06:05



proszę dodaj opis również do odpowiedzi. - nullpointer
Bardzo dobra odpowiedź. Zasadniczo polega na tym, że rzutuje ArraySlice <T> na tablicę. Osobiście nie uwzględniłbym tylu asserów. Ponieważ zwykle chcę, aby plaster się nie sprawdzał, jeśli dostarczę fałszywe zakresy itp. - eonist