2

Let's say I have this array of strings:

let Vehicles = ["Aeroplane", "Bicycle", "CarVehicle", "Lorry", "Motorbike", "Scooter", "Ship", "Train"]

What I want is this result:

let resultArray = [["Aeroplane", "Bicycle", "CarVehicle", "Lorry"], ["Motorbike", "Scooter", "Ship", "Train"]]

I know I could do this by for but I want to use Higher Order functions in Swift. I mean functions like map, reduce, filter. I think it's possible to do this way and it could be better. Can anyone help me with this? Thanks

1
  • See my answer to a very similar question that offers up to 5 different ways to solve your problem. Commented Mar 9, 2017 at 23:58

1 Answer 1

5

A possible solution with map() and stride():

let vehicles = ["Aeroplane", "Bicycle", "CarVehicle", "Lorry", "Motorbike", "Scooter", "Ship", "Train"]
let each = 4

let resultArray = map(stride(from: 0, to: vehicles.count, by: each)) {
    vehicles[$0 ..< advance($0, each, vehicles.count)]
}

println(resultArray)
// [[Aeroplane, Bicycle, CarVehicle, Lorry], [Motorbike, Scooter, Ship, Train]]

The usage of advance() in the closure guarantees that the code works even if the number of array elements is not a multiple of 4 (and the last subarray in the result will then be shorter.)

You can simplify it to

let resultArray = map(stride(from: 0, to: vehicles.count, by: each)) {
    vehicles[$0 ..< $0 + each]
}

if you know that the number of array elements is a multiple of 4.

Strictly speaking the elements of resultArray are not arrays but array slices. In many cases that does not matter, otherwise you can replace it by

let resultArray = map(stride(from: 0, to: vehicles.count, by: each)) {
    Array(vehicles[$0 ..< advance($0, each, vehicles.count)])
}
Sign up to request clarification or add additional context in comments.

3 Comments

Looks like what I was looking for. I forget mention that number of elements don't need to be multiple of 4 so thanks for first solution. One more thing. I have problem that I have result as ArraySlice<String> not [String]. How can I fix it?
@MartinR Would it also be possible to do it with reduce and map together?
@JacobsonTalom: It would be possible with reduce(), but then a "nested array" would be created in each call of the reduce closure, so that is probably less effective. Of course there might be another solution that I did not think of.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.