'How to Remove Every Other Element in an Array in Swift?

So say I have an array:

var stringArray = ["a","b","c","d","e","f","g","h","i","j"]

Now, how do I delete "a", "c", "e", "g", and "i" (all the even number indexes from the array)?

Thanks!



Solution 1:[1]

Instead of using C-style for-loops (which are set to be deprecated in an upcoming version of Swift), you could accomplish this using strides:

var result = [String]()
for i in stride(from: 1, through: stringArray.count - 1, by: 2) {
    result.append(stringArray[i])
}

Or for an even more functional solution,

let result = stride(from: 1, to: stringArray.count - 1, by: 2).map { stringArray[$0] }

Solution 2:[2]

Traditional

var filteredArray = []
for var i = 1; i < stringArray.count; i = i + 2 {
    filteredArray.append(stringArray[i])
}

Functional alternative

var result = stringArray.enumerate().filter({ index, _ in
    index % 2 != 0
}).map { $0.1 }

enumerate takes a array of elements and returns an array of tuples where each tuple is an index-array pair (e.g. (.0 3, .1 "d")). We then remove the elements that are odd using the modulus operator. Finally, we convert the tuple array back to a normal array using map. HTH

Solution 3:[3]

There are a bunch of different ways to accomplish this, but here are a couple that I found interesting:

Using flatMap() on indices:

let result: [String] = stringArray.indices.flatMap {
    if $0 % 2 != 0 { return stringArray[$0] }
    else { return nil }
}

Note: result needs to be defined as a [String] otherwise the compiler doesn't know which version of flatMap() to use.

Or, if you want to modify the original array in place:

stringArray.indices.reverse().forEach {
    if $0 % 2 == 0 { stringArray.removeAtIndex($0) }
}

In this case you have to call reverse() on indices first so that they're enumerated in reverse order. Otherwise by the time you get to the end of the array you'll be attempting to remove an index that doesn't exist anymore.

Solution 4:[4]

Swift 4.2

A function accepting generics and producing reduced result

func stripElements<T>(in array:[T]) -> [T] {
    return array.enumerated().filter { (arg0) -> Bool in
        let (offset, _) = arg0
        return offset % 2 != 0
        }.map { $0.element }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user1687195
Solution 2
Solution 3 Mike S
Solution 4 kokoko