I have an array tags
which include several elements with id
and name
. I also have an array order
where some of the elements in tags
are present. Here is what I want to achieve:
- All elements in
tags
should be sorted according toorder
. - Those elements which is not present in
order
should be ordered alphabetically after the elements which are present inorder
.
I have solved it using a for
loop (the code runs in Playground):
import Foundation
import UIKit
struct Tag: Identifiable {
var id: Int
var name: String
}
// Ccc > Bbb > Aaa > Ddd > Eee
var tags = [Tag(id: 1000, name: "Ccc"), Tag(id: 1001, name: "Bbb"), Tag(id: 1002, name: "Aaa"), Tag(id: 1003, name: "Ddd"), Tag(id: 1004, name: "Eee")]
// Eee > Ddd > Ccc > Bbb > Aaa
tags.sort(by: { $0.name < $1.name })
// Bbb > Ddd
var idOrdering = [1001, 1003]
// Bbb > Ddd > Aaa > Ccc > Eee
for orderIndex in idOrdering.indices {
// Get tag id.
let tagId = idOrdering[orderIndex]
let tagIndex = tags.firstIndex(where: { $0.id == tagId })
// Remove tag from original array and place it according to the `order`.
let removedTag = tags.remove(at: tagIndex!)
tags.insert(removedTag, at: orderIndex)
}
// Print the result.
tags.forEach {
print($0.name)
}
The order of the elements in the original tags
is Ccc > Bbb > Aaa > Ddd > Eee
. Two of the elements named Bbb
and Ddd
should be ordered based on order
, that is, Bbb > Ddd
. The rest should be ordered alphabetically. In other words, the end result should be Bbb > Ddd > Aaa > Ccc > Eee
. Although the for
loop above works, how can I solve this problem more efficiently?