-1

I've seen this SO question (How to return an subset of Array of characters?) but the problem is it is only dealing with a one-off return of the first characters of a string.

I'm trying to achieve something different but am not sufficiently familiar with the Swift language to know what functionality I need.

My problem is as follows, I've got an array:

["10", "44", "33", "31", "38", "49", "8", "4", "40"]

What would be the "Swift 4.2" way to return, for example, groups of three, i.e. :

["10", "44", "33"]
["31", "38", "49"]
["8", "4", "40"]

Also bear in mind the array may not always be exactly divisible (e.g. the above example array could easily have 10 values not 9) , so I would need to ignore any "excess" numbers at the end of the array.

Little Code
  • 1,315
  • 2
  • 16
  • 37

1 Answers1

1

Use map on array created by using stride. As to pass last index of item in array which can be divisible by three without the rest (excess numbers will be ignored). Now inside map closure return array of elements with indexes $0...$0+2

let array = ["10", "44", "33", "31", "38", "49", "8", "4", "40"]
let finalArray = stride(from: 0, to: array.endIndex - (array.endIndex % 3), by: 3).map {
    Array(array[$0...$0+2])
}
Robert Dresler
  • 10,580
  • 2
  • 22
  • 40
  • Interesting, I just discovered the stride function but I didn't make the connection to being able to use it for this application. Thanks !!! – Little Code Dec 22 '18 at 11:50
  • Doesn't work for arrays with a count that is not a multiple of 3. This question is a duplicate. have a look at matt's answer [here](https://stackoverflow.com/a/52856224/2907715) – ielyamani Dec 22 '18 at 11:55
  • @Carpsen90 I noticed, but your comment was written earlier – Robert Dresler Dec 22 '18 at 11:58
  • 1
    Don't you think this a duplicate question? and a better answer is given there? Answering duplicates [is discouraged](https://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled). Anyway, you could make your solution shorter `finalArray.append(Array(array[n...min(n+2, array.count - 1)]))`. There are other improvements that would make it faster... – ielyamani Dec 22 '18 at 12:18
  • 1
    @Carpsen90 yes I agree, it's similar but; from OP's question: *...so I would need to ignore any "excess" numbers at the end of the array* – Robert Dresler Dec 22 '18 at 12:46
  • this checks unnecessarily every iteration the array count property. It would be much easier to remove the guard, change the result to ArraySlice and use a range like `$0.. – Leo Dabus Dec 22 '18 at 13:48
  • `let final = stride(from: 0, to: array.endIndex, by: 3).map { array[$0.. – Leo Dabus Dec 22 '18 at 13:51
  • @LeoDabus with using `map` I agree. Anyway if they should be less than three items in last array, he wants to ignore these items – Robert Dresler Dec 22 '18 at 13:54
  • Just drop the excess if needed using `array.dropLast(array.endIndex % 3)` – Leo Dabus Dec 22 '18 at 13:55
  • `let array = ["10", "44", "33", "31", "38", "49", "8", "4", "40","1"] let trimmed = array.dropLast(array.endIndex % 3) let final = stride(from: 0, to: trimmed.endIndex, by: 3).map { Array(trimmed[$0..<$0+3]) } print(final)` – Leo Dabus Dec 22 '18 at 13:58
  • @LeoDabus yes, I wrote a solution, a just need to rewrite answer – Robert Dresler Dec 22 '18 at 13:59
  • @LeoDabus btw thank you! – Robert Dresler Dec 22 '18 at 13:59