How to return first 5 objects of Array in Swift?

后端 未结 13 1642
春和景丽
春和景丽 2020-12-07 09:47

In Swift, is there a clever way of using the higher order methods on Array to return the 5 first objects? The obj-c way of doing it was saving an index, and for-loop throug

相关标签:
13条回答
  • 2020-12-07 10:26

    SWIFT 4

    A different solution:

    An easy inline solution that wont crash if your array is too short

    [0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 3 ? $0.element : nil }
    

    But works fine with this.

    [0,1,2,3,4,5].enumerated().compactMap{ $0.offset < 1000 ? $0.element : nil }
    

    Usually this would crash if you did this:

    [0,1,2,3,4,5].prefix(upTo: 1000) // THIS CRASHES
    
    [0,1,2,3,4,5].prefix(1000) // THIS DOESNT
    
    0 讨论(0)
  • 2020-12-07 10:27

    I slightly changed Markus' answer to update it for the latest Swift version, as var inside your method declaration is no longer supported:

    extension Array {
        func takeElements(elementCount: Int) -> Array {
            if (elementCount > count) {
                return Array(self[0..<count])
            }
            return Array(self[0..<elementCount])
        }
    }
    
    0 讨论(0)
  • 2020-12-07 10:29

    Update: There is now the possibility to use prefix to get the first n elements of an array. Check @mluisbrown's answer for an explanation how to use prefix.

    Original Answer: You can do it really easy without filter, map or reduce by just returning a range of your array:

    var wholeArray = [1, 2, 3, 4, 5, 6]
    var n = 5
    
    var firstFive = wholeArray[0..<n] // 1,2,3,4,5
    
    0 讨论(0)
  • 2020-12-07 10:33

    For getting the first 5 elements of an array, all you need to do is slice the array in question. In Swift, you do it like this: array[0..<5].

    To make picking the N first elements of an array a bit more functional and generalizable, you could create an extension method for doing it. For instance:

    extension Array {
        func takeElements(var elementCount: Int) -> Array {
            if (elementCount > count) {
                elementCount = count
            }
            return Array(self[0..<elementCount])
        }
    }
    
    0 讨论(0)
  • 2020-12-07 10:34

    For an array of objects you can create an extension from Sequence.

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

    Usage:

    struct Apple {}
    
    let apples: [Apple] = [Apple(), Apple(), Apple()]
    let limitTwoApples = apples.limit(2)
    
    // limitTwoApples: [Apple(), Apple()]
    
    0 讨论(0)
  • 2020-12-07 10:37

    By far the neatest way to get the first N elements of a Swift array is using prefix(_ maxLength: Int):

    let someArray = [1, 2, 3, 4, 5, 6, 7]
    let first5 = someArray.prefix(5) // 1, 2, 3, 4, 5
    

    This has the benefit of being bounds safe. If the count you pass to prefix is larger than the array count then it just returns the whole array.

    NOTE: as pointed out in the comments, Array.prefix actually returns an ArraySlice, not an Array. In most cases this shouldn't make a difference but if you need to assign the result to an Array type or pass it to a method that's expecting an Array param you will need to force the result into an Array type: let first5 = Array(someArray.prefix(5))

    0 讨论(0)
提交回复
热议问题