0

I'd like to take an array of structs (with a date property) and split that array into an array of arrays where each subarray contains items with dates in the same calendar month.

I just can't get my head around how to split/group them etc...

I could just create a var array and iterate the array depositing items as I go but I believe there is a much nicer (more functional, more Swifty) way to do it.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 2
    Have a look at [How to group by the elements of an array in Swift](https://stackoverflow.com/questions/31220002/how-to-group-by-the-elements-of-an-array-in-swift), in particular the solutions using [`Dictionary(grouping:by:)`](https://developer.apple.com/documentation/swift/dictionary/2919592-init) – Martin R Nov 28 '17 at 14:20

1 Answers1

0

Here it is very fast:

struct Withdate {
  let value: String
  let month: Month
}

enum Month: Int {
  case Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
}

let firstArray = [Withdate(value: "111", month: .Jan), Withdate(value: "112", month: .Jan), Withdate(value: "441", month: .Apr), Withdate(value: "442", month: .Apr), Withdate(value: "991", month: .Sep), Withdate(value: "992", month: .Sep)]

var objectsDict = [Month: [Withdate]]()

firstArray.forEach { if objectsDict[$0.month] == nil { objectsDict[$0.month] = [Withdate]()  }
objectsDict[$0.month]!.append($0) }
let finalArray = Array(objectsDict.values.map{ $0 })

print(finalArray) // will return:

[[main.Withdate(value: "111", month: main.Month.Jan), main.Withdate(value: "112", month: main.Month.Jan)], [main.Withdate(value: "441", month: main.Month.Apr), main.Withdate(value: "442", month: main.Month.Apr)], [main.Withdate(value: "991", month: main.Month.Sep), main.Withdate(value: "992", month: main.Month.Sep)]]
Serhii Didanov
  • 2,200
  • 1
  • 16
  • 31