Issue #672
Supposed we want to stitch magazines array into books array. The requirement is to sort them by publishedDate
, but must keep preferredOrder
of books. One way to solve this is to declare an enum to hold all possible cases, and then do a sort that check every possible combination
struct Book {
let preferredOrder: Int
let publishedDate: Date
}
struct Magazine {
let publishedDate: Date
}
enum StitchItem {
case book(Book)
case magazine(Magazine)
}
func stitch(_ books: [Book], magazines: [Magazine]) -> [StitchItem] {
let items = books.map({ StitchItem.book($0) }) + magazines.map({ StitchItem.magazine($0) })
return items.sorted(by: { book, magazine in
switch (book, magazine) {
case let (.book(b1), .book(b2)):
return b1.preferredOrder < b2.preferredOrder
case let (.book(book), .magazine(magazine)):
if book.publishedDate == magazine.publishedDate {
return true
} else {
return book.publishedDate < magazine.publishedDate
}
case let (.magazine(magazine), .book(book)):
if book.publishedDate == magazine.publishedDate {
return false
} else {
return book.publishedDate < magazine.publishedDate
}
case let (.magazine(m1), .magazine(m2)):
return m1.publishedDate < m2.publishedDate
}
})
}
The above sort function declares the intention but Swift just sort
instead of trying to fully meet our requirements.
A manual solution is to sort each array first then use while loop to insert.
func stitch(_ books: [Book], magazines: [Magazine]) -> [StitchItem] {
let books = books
.sorted(by: { $0.preferredOrder < $1.preferredOrder })
let magazines = magazines
.sorted(by: sortmagazines)
var bookIndex = 0
var magazineIndex = 0
var results: [StitchItem] = []
while (bookIndex < books.count && magazineIndex < magazines.count) {
let book = books[bookIndex]
let magazine = magazines[magazineIndex]
if book.publishedDate < magazine.publishedDate {
results.append(StitchItem.book(book))
bookIndex += 1
} else {
results.append(StitchItem.magazine(magazine))
magazineIndex += 1
}
}
while (bookIndex < books.count) {
let book = books[bookIndex]
results.append(StitchItem.book(book))
bookIndex += 1
}
while (magazineIndex < magazines.count) {
let magazine = magazines[magazineIndex]
results.append(StitchItem.magazine(magazine))
magazineIndex += 1
}
return results
}
Updated at 2020-08-31 12:19:33