I have a NSSet
(from CoreData
) containing Element
with a column
and row
properties (both Int16
).
I want to efficiently convert this NSSet
to an array of array [[Element]]
(it would be an array of the columns and the value would be an array of rows in the columns) in a way that it handles holes in coordinates and respect order.
So for example, if I have a the following elements:
let mySet = NSSet([
Element(column: 1, row: 1, id: 'el1'),
Element(column: 3, row: 0, id: 'el2),
Element(column: 3, row: 2, id: 'el3'),
Element(column: 6, row: 12, id: 'el4'),
Element(column: 6, row: 6, id: 'el5),
Element(column: 6, row: 1, id: 'el6')
]);
// I would get an array like:
let resultArray = [
[el1],
[el2, el3],
[el6, el5, el4]
]
I tried various solution like Dictionary(grouping: ..)
, reduce
, etc... but can't manage to make it works properly.
The code doesn't compile.
Dictionary(grouping:by:)
is indeed a possible way.
Set<Element>
column
property and get the values
id
values and sort the outer array by its first itemlet resultArray = Dictionary(grouping: mySwiftSet, by: \.column)
.values
.map { items in
items.map(\.id).sorted()
}
.sorted(by: {$0.first! < $1.first!})
or with reduce(into:)
let resultArray = Dictionary(grouping: mySwiftSet, by: \.column)
.reduce(into: [[String]]()) {
$0 += [$1.value.map(\.id).sorted()]
}
.sorted(by: {$0.first! < $1.first!})
Or you can get a nested array of Element
, the inner array sorted by row and the outer by column.
let resultArray = Dictionary(grouping: mySwiftSet, by: \.column)
.reduce(into: [[Element]]()) {
$0 += [$1.value.sorted(by:{$0.row < $1.row} )]
}
.sorted(by: {$0.first!.column < $1.first!.column})