You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI基于JSON数据和自定义属性实现餐厅列表排序相关问题

解决方案

1. 按JSON原生字段排序的实现

你直接调用.sort()方法无效的原因是Categories结构体未遵守Comparable协议,系统无法默认判断排序规则。你不需要额外遵守协议,直接使用带闭包的排序方法即可自定义任意字段的排序规则:

  • 按名称字母正序排序:
restaurantInfo.restaurantList.sort { $0.name < $1.name }
  • 按星级从高到低排序:
restaurantInfo.restaurantList.sort { $0.stars > $1.stars }

把闭包里的字段换成你模型里的其他属性,就能实现对应字段的排序,需要倒序就把<替换为>即可。

2. 非JSON来源字段的排序实现

对于营业状态、距离这类动态计算的非JSON原生字段,直接在排序闭包内调用你的计算逻辑即可:

按营业状态排序(营业在前,歇业在后)

假设你视图模型中判断营业状态的方法为func checkStatus(of restaurant: Categories) -> String,排序代码如下:

restaurantInfo.restaurantList.sort { res1, res2 in
    let status1 = checkStatus(of: res1)
    let status2 = checkStatus(of: res2)
    // 状态相同则按名称次级排序
    if status1 == status2 {
        return res1.name < res2.name
    }
    // 营业的排在前面
    return status1 == "open" && status2 == "closed"
}

按距离排序

结合你获取的用户位置,直接计算坐标距离排序即可:

restaurantInfo.restaurantList.sort { res1, res2 in
    let loc1 = CLLocation(latitude: res1.coordinates[0], longitude: res1.coordinates[1])
    let loc2 = CLLocation(latitude: res2.coordinates[0], longitude: res2.coordinates[1])
    // 距离从小到大排序
    return loc1.distance(from: location.userLocation) < loc2.distance(from: location.userLocation)
}

3. @Published修饰列表追加报错的解决

@Published本身对存储的元素类型没有额外协议要求,报错几乎都是类型不匹配导致的:

  • 如果你要存储餐厅名称,需要声明对应类型的列表:
// 视图模型内声明
@Published var restaurantNameList: [String] = []
  • 追加元素时确保元素类型和列表声明的元素类型一致:
// 正确:追加String类型的名称
restaurantNameList.append(restaurant.name)
// 错误:如果列表声明为[String],追加Categories类型对象会报错
restaurantNameList.append(restaurant)

你只需要检查列表声明的元素类型和你追加的元素类型是否一致即可解决问题。

内容的提问来源于stack exchange,提问作者sadel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:15:02