如何将两个不同的结构组合成一个数组并进行排序?斯威夫特



我正在构建一个提要,我想在其中统一两个不同的结构并按日期对提要进行排序,下面是我的尝试。它在视图中显示错误。它写的要么是"编译器无法在合理时间内输入检查",要么是与ForEach循环相连的其他东西。也许你知道什么是问题?或者,是否有其他方法来构建和排序提要?

编辑如下错误: "编译器无法在合理的时间内对该表达式进行类型检查;试着把表达式分解成不同的子表达式">

class FeedViewModel: ObservableObject {
@Published var feed: [FeedCommonContent] = []
// download(ed) articles
self.feed.append(Article(id: doc.document.documentID, title: title, pic: pic, time: time.dateValue(), user: user))
// download(ed) tutorials
self.feed.append(Tutorial(id: doc.document.documentID, title: title, steps: [steps], notes: notes, pic: pic, time: time.dateValue(), user: user))
// sort the feed
self.feed.sort { (p1, p2) -> Bool in
return p1.time > p2.time
}

}

protocol FeedCommonContent {
// Define anything in common between objects
var time: Date { get set }
var id: String { get set }
var feedIdentity: FeedIdentity.RawValue { get } // Article, or Tutorial; or - { get set }
}
enum FeedIdentity: String {
// case Article, Tutorial
case Article = "Article"
case Tutorial = "Tutorial"

}

struct Article: Identifiable, FeedCommonContent {
var feedIdentity = FeedIdentity.Article.rawValue
var id: String = UUID().uuidString
var title: String
var pic: String
var time: Date
var user: User
}
struct Tutorial: Identifiable, FeedCommonContent {
var feedIdentity = FeedIdentity.Tutorial.rawValue
var id: String = UUID().uuidString
var titleImage: String
var name: String
var user: User
var inventory: [String]
var steps: [String]
var notes: String
var time: Date
var warnings: String
}
struct FeedView: View {

@StateObject var feedData = FeedViewModel()

var body: some View {
ScrollView {
ForEach(feedData.feed, id: .self.id) { item in

// also tried type checking:
// if item is Article // or, if let article = item as? Article
if item.feedIdentity == FeedIdentity.Article.rawValue {
NavigationLink(destination: ArticleView(article: item, articleData: feedData)) {
ArticleUnitView(article: item, feedData: feedData)
}

} else if item.feedIdentity == FeedIdentity.Tutorial.rawValue { //  if item is Tutorial
NavigationLink(destination: TutorialView(tutorial: item, feedData: feedData)) {
TutorialUnitView(tutorial: item, feedData: feedData)
}

}
}
}

当我只处理一种数据结构的数组时,所有的数据结构都可以工作。(即var articles: [Article] = []var tutorials: [Tutorial] = []等)

这是我用来展示如何进行排序的(测试)代码按日期设置提要,并在视图中显示:

编辑,使用Joakim Danielson"enum建议:

import SwiftUI
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
FeedView()
}
}
}
class FeedViewModel: ObservableObject {

@Published var feed: [FeedCommonContent] = []

// for testing
init() {
self.feed.append(Article(title: "article title", pic: "pic1", time: Date(), user: User()))
self.feed.append(Tutorial(titleImage: "title1", name: "tut1", user: User(), inventory: [], steps: [], notes: "note1", time: Date(), warnings: ""))
sortFeed()
}

func sortFeed() {
feed.sort { $0.time > $1.time }
}
}
protocol FeedCommonContent {
// Define anything in common between objects
var time: Date { get set }
var id: String { get set }
var feedIdentity: FeedIdentity { get } // Article, or Tutorial; or - { get set }
}
enum FeedIdentity: String {
// case Article, Tutorial
case Article 
case Tutorial   
}
struct User: Identifiable {
var id: String = UUID().uuidString
var name: String = "user"
}
struct Article: Identifiable, FeedCommonContent {
let feedIdentity = FeedIdentity.Article
var id: String = UUID().uuidString
var title: String
var pic: String
var time: Date
var user: User
}
struct Tutorial: Identifiable, FeedCommonContent {
let feedIdentity = FeedIdentity.Tutorial
var id: String = UUID().uuidString
var titleImage: String
var name: String
var user: User
var inventory: [String]
var steps: [String]
var notes: String
var time: Date
var warnings: String
}
struct FeedView: View {

@StateObject var feedData = FeedViewModel()

var body: some View {
ScrollView {
ForEach(feedData.feed, id: .id) { item in

//                switch item.feedIdentity {
//                case FeedIdentity.Article:
//                    NavigationLink(destination: ArticleView(article: item, articleData: feedData)) {
//                        ArticleUnitView(article: item, feedData: feedData)
//                    }
//                case FeedIdentity.Tutorial:
//                    NavigationLink(destination: TutorialView(tutorial: item, feedData: feedData)) {
//                        TutorialUnitView(tutorial: item, feedData: feedData)
//                    }
//                }

// for testing
switch item.feedIdentity {
case FeedIdentity.Article:
NavigationLink(destination: Text(item.feedIdentity.rawValue + " " + item.id)) {
Text(item.feedIdentity.rawValue)
}
case FeedIdentity.Tutorial:
NavigationLink(destination: Text(item.feedIdentity.rawValue + " " + item.id)) {
Text(item.feedIdentity.rawValue)
}
}
}
}
}

最新更新