HiveBrain v1.2.0
Get Started
← Back to all entries
patternswiftMinor

Efficient way in Swift to trim an array

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
swifttrimarrayefficientway

Problem

Let's say I have a struct…

struct Person {
   let isMale: Bool
   let name: String
}


and an array of Person structs. I want to trim all the men (isMale == true) from the start and end of the array (similarly to how you'd trim whitespace from the start & end of a string)…

func trimMen(people: [Person]) -> [Person]

    var trimmedPeople: [Person] = people

    while trimmedPeople.first?.isMale {
        trimmedPeople.removeFirst()
    }
    while trimmedPeople.last?.isMale {
        trimmedPeople.removeLast()
    }
    return trimmedPeople
}


Is there a more efficient way to do it?

Solution

Following implementation provides generic solution, which mimics other foundation methods like filter, map etc. Though extends Array instead of SequenceType.

Main benefit from this solution comparing to the original provided by Ashley Mills is that it does not mutate an array.

extension Array {

    func trim(@noescape predicate: (Element) throws -> Bool) rethrows -> [Element] {
        guard let
            start = try (indexOf { try !predicate($0) }),
            end = try (reverse().indexOf { try !predicate($0) }) else {
                return []
        }
        return Array(self[start..<end.base])
    }

}


Usage Example:

persons.trim { $0.isMale }

Code Snippets

extension Array {

    func trim(@noescape predicate: (Element) throws -> Bool) rethrows -> [Element] {
        guard let
            start = try (indexOf { try !predicate($0) }),
            end = try (reverse().indexOf { try !predicate($0) }) else {
                return []
        }
        return Array(self[start..<end.base])
    }

}
persons.trim { $0.isMale }

Context

StackExchange Code Review Q#139442, answer score: 4

Revisions (0)

No revisions yet.