Как создать новый список с информацией, рассчитанной на основе другой информации в моем json?

#swift #xcode #swiftui #xcode12

Вопрос:

#вот моя модель представления#

 import Foundation

class CategoriesModel:ObservableObject {
    
    @Published var restaurantList = [Categories]()
    
    init() {
        //get path to json data
        let pathString = Bundle.main.path(forResource: "data", ofType: "json")
        
        if let path = pathString {
            
            // create url object
            let url = URL(fileURLWithPath: path)
            
            do {
                //create data object with data at url
                let data = try Data(contentsOf: url)
                
                let decoder = JSONDecoder()
                
                do {
                    let restaurantData = try decoder.decode([Categories].self, from: data)
                    
                    self.restaurantList = restaurantData
                    //restaurantList.shuffle()
                
                }
                catch {
                    //error decoding json
                    print(error)
                }
                
            }
            catch {
                //error fetching url
                print(error)
            }
            
            
        }
        
        
    }
}
 

#вот моя модель#

 import Foundation

struct Categories: Identifiable, Decodable {
    
    var id = 0
    var name:String = ""
    var truckOrRestaurant = ""
    var type:[String] = [String]()
    var pic:String = ""
    var price:String = ""
    var hours:[String:[String]] = [String:[String]]()
    var hoursString:String = ""
    var stars:String = ""
    var website:String = ""
    var location:String = ""
    var coordinates:[Double] = [Double]()
    var phoneNumber:String = ""
    var currency:String = ""
    var review:String = ""
    var wait:String = ""
    
}
 

#некоторые из моих взглядов#

 import SwiftUI
import MapKit

struct DiscoverTab: View {
    
    @EnvironmentObject var restaurantInfo:CategoriesModel
    @StateObject private var location = LocationCode()
    
    var body: some View {
        
        
        VStack {
            HStack {
                Text("Sort by:")
                Button(action:{
                    //sort alphabetically
                    //restaurantInfo.restaurantList.sort()
                }, label:{
                    Text("Alphabetical")
                        .background(Color.yellow)
                        .foregroundColor(.black)
                        .cornerRadius(5)
                        
                })
                Button(action:{
                    //sort alphabetically
                    //restaurantInfo.restaurantList.sort()
                }, label:{
                    Text("Distance")
                        .background(Color.yellow)
                        .foregroundColor(.black)
                        .cornerRadius(5)
                })
...
 

Я считаю, что мне нужно использовать какие-то другие свойства в модели, но как я сортирую в алфавитном порядке (.sort() не работает) и по разным частям информации, найденной в моем json. Кроме того, как бы я сортировал данные, которые не поступают из моего json? У меня в viewmodel есть другая функция, которая возвращает «открыто», если ресторан открыт в любой момент времени, или наоборот «закрыто». Всякий раз, когда я пытаюсь создать новый опубликованный список в своей модели просмотра и добавить к нему название ресторана, я получаю ошибку. Есть ли какой-то дополнительный протокол, который мне нужно использовать, или что-то в этом роде?

Ответ №1:

Рекомендуемый способ — сортировать данные в модели представления.

Прежде всего назовите модель в единственном числе Category , один экземпляр-это одна категория

 struct Category: Identifiable, Decodable {
 

в CategoriesModel разделе добавить метод сортировки массива по ключевым путям

 func sort<T : Comparable>(keyPath: KeyPath<Category,T>) {
    restaurantList.sort { c1, c2 in
        c1[keyPath: keyPath] < c2[keyPath: keyPath]
    }
}
 

Затем в действии кнопки вызовите пользовательский метод сортировки

 Button(action:{
    //sort alphabetically
    restaurantInfo.restaurantList.sort(keyPath: .name)
}
 

Для расстояния вы должны добавить логику также в модель представления

Комментарии:

1. Как бы я сортировал данные, которые не поступают из моего json? У меня в viewmodel есть другая функция, которая возвращает «открыто», если ресторан открыт в любой момент времени, или «закрыто» наоборот. Всякий раз, когда я пытаюсь создать новый опубликованный список в своей модели просмотра и добавить к нему название ресторана, я получаю сообщение об ошибке. Есть ли какой-то дополнительный протокол, который мне нужно использовать, или что-то в этом роде?

2. Это еще один вопрос, и он требует дополнительной информации.

3. Спасибо, я не сомневаюсь, что это правильный ответ, я всего лишь начинающий программист, и я все еще пытаюсь найти это решение.