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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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