在Swift中,是否有一种聪明的方法来使用数组上的高阶方法来返回5个第一个对象? obj-c的方法是保存一个索引,而for-loop则通过数组将索引值递增到5,然后返回新的数组。有办法做到这一点与过滤器,映射或减少?


当前回答

为了获取数组的前5个元素,你所需要做的就是对数组进行切片。在Swift中,你可以这样做:array[0..<5]。

为了使选择数组的前N个元素更具功能性和可泛化性,您可以创建一个扩展方法来执行此操作。例如:

extension Array {
    func takeElements(var elementCount: Int) -> Array {
        if (elementCount > count) {
            elementCount = count
        }
        return Array(self[0..<elementCount])
    }
}

其他回答

到目前为止,获得Swift数组的前N个元素的最利落的方法是使用prefix(_ maxLength: Int):

let array = [1, 2, 3, 4, 5, 6, 7]
let slice5 = array.prefix(5) // ArraySlice
let array5 = Array(slice5)   // [1, 2, 3, 4, 5]

一句话是:

let first5 = Array(array.prefix(5))

这样做的好处是边界安全。如果传递给prefix的计数大于数组计数,则它只返回整个数组。

注:如评论中所指出,阵列。prefix实际上返回一个ArraySlice,而不是Array。

如果你需要将结果赋值给一个Array类型,或者将它传递给一个期望数组参数的方法,你将需要强制将结果转换为Array类型:

简单明了

extension Array {
    func first(elementCount: Int) -> Array {
          let min = Swift.min(elementCount, count)
          return Array(self[0..<min])
    }
}

斯威夫特4

要获取Swift数组的前N个元素,可以使用prefix(_ maxLength: Int):

Array(largeArray.prefix(5))

对于对象数组,您可以从Sequence创建一个扩展。

extension Sequence {
    func limit(_ max: Int) -> [Element] {
        return self.enumerated()
            .filter { $0.offset < max }
            .map { $0.element }
    }
}

用法:

struct Apple {}

let apples: [Apple] = [Apple(), Apple(), Apple()]
let limitTwoApples = apples.limit(2)

// limitTwoApples: [Apple(), Apple()]

Prefix函数绝对是解决这个问题的最有效的方法,但是你也可以像下面这样使用for-in循环:

let array = [1,2,3,4,5,6,7,8,9]
let maxNum = 5
var iterationNumber = 0
var firstNumbers = [Int()]
if array.count > maxNum{
  for i in array{
    iterationNumber += 1
    if iterationNumber <= maxNum{
      firstNumbers.append(i)
    }
  }
  firstNumbers.remove(at: 0)
  print(firstNumbers)
} else {
  print("There were not \(maxNum) items in the array.")
}

这个解决方案占用了很多行代码,但会检查数组中是否有足够的项来执行程序,然后继续并解决问题。 该解决方案使用了许多基本函数,包括数组。Count,它返回数组中项的数量,而不是数组中最后一项的位置。它也使用数组。Append,它把东西添加到数组的末尾。最后,它使用数组。Remove,删除具有指定位置的数组项。

我已经测试过了,它至少适用于swift 5。