索引范围Swift中的新数组

时间:2014-06-04 09:58:21

标签: arrays 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
}

5 个答案:

答案 0 :(得分:155)

这对我有用:

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 :(得分:77)

使用Swift 4时,写下:

let newNumbers = numbers[0...position]

newNumbers不属于Array<Int>类型,但属于ArraySlice<Int>类型。这是因为Array subscript(_:​)返回ArraySlice<Element>,根据Apple的说法,它会显示一些较大阵列的存储视图。

此外,Swift还为init(_:​)提供Array初始值设定项,允许我们从sequence(包括ArraySlice)创建新数组。

因此,您可以使用以下四种方法之一来获取数组的第一个 n 元素的新数组。

#1。使用范围

Array下标

您可以将Array下标与CountableRangeCountableClosedRangePartialRangeUpTopartialRangeThrough一起使用,以获取数组第一个元素的子序列。

用法:

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。使用Array&#39; prefix(_:)方法

Swift为符合prefix(_:)协议(包括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]

#3。创建自定义全局函数

以下Playground代码显示为创建一个返回Array的第一个 n 元素的全局函数:

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。创建Array扩展自定义方法

以下Playground代码显示为创建Array扩展自定义方法,该方法返回Array的第一个 n 元素:

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]

答案 2 :(得分:5)

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

答案 3 :(得分:0)

使用extension和参数名称range的另一个变体

此扩展名使用RangeClosedRange

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)
}

答案 4 :(得分:0)

数组功能方式:

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

范围:

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

此方法的优点是这样的实现是安全的。