How to transform array to 2d array using reduce(into:_:)?
我有一组自定义模型:
1 2 3 4 | struct Event { var day: Int // let's assume its Int for now var title: String } |
为:
1 2 3 4 | let array = [Event(day: 1, title:"Pizza Party!"), Event(day: 1, title:"Another Pizza Party"), Event(day: 2, title:"Cinema - Moive 01"), Event(day: 2, title:"Cinema - Moive 02")] |
我想将
1 2 3 4 | [ [Event(day: 1, title:"Pizza Party!"), Event(day: 1, title:"Another Pizza Party")] [Event(day: 2, title:"Cinema - Moive 01"), Event(day: 2, title:"Cinema - Moive 02")] ] |
第一个数组(在外部2d数组中)包含第
是否可以使用
尽管想使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | func transfrom(_ models: [Event]) -> [[Event]] { let uniqueDates = Set(array.map { $0.day }).sorted() var twoDArray = [[Event]]() for date in uniqueDates { var array = [Event]() for model in models { if date == model.day { array.append(model) } } twoDArray.append(array) } return twoDArray } let transfomredArray = transfrom(array) // wanted result |
您可以使用Dictionary的分组功能来满足您的要求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // This dictionary will have all your events grouped based on the day it belongs to. let dict = Dictionary(grouping: array) { (element) -> Int in return element.day } // If you need a sorted list of events based on the day. let groupedItems = dict.sorted { return $0.key < $1.key } // groupedItems would now have all the data, grouped and ready to be used. for day in groupedItems { print("\\(day.key): \\(day.value.count)") } |
要以更简单的方式进行操作,可以使用@MartinR的注释:
1 | let resultArray = Dictionary(grouping: array, by: { $0.day }).values |
但是您可能要对它执行一些额外的操作,可以说是排序。然后,您可以使用以下方法:
根据
1 | let grouped = Dictionary(grouping: array, by: { $0.day }) |
根据键对分组的数据进行排序。结果将是
1 | let sorted = grouped.sorted(by: { $0.key < $1.key }) |
您可以使用
1 | let resultArray: [[Event]] = sorted.reduce([]) { $0 + [$1.value] } |
如果您仍然想要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | let result: [[Event]] = array.sorted { $0.day < $1.day } .reduce(into: [[Event]]()) { tempo, event in if let lastArray = tempo.last { if lastArray.first?.day == event.day { let head: [[Event]] = Array(tempo.dropLast()) let tail: [[Event]] = [lastArray + [event]] tempo = head + tail } else { tempo.append([event]) } } else { tempo = [[event]] } } |