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

Swift中如何按punteggio字段对Squadre数组排序并在List展示?

问题解决:SwiftUI中按punteggio排序List内容

核心问题分析

你当前的排序代码无效有两个原因:

  1. sort(using:)是原地修改数组的mutating方法,不能直接赋值给存储属性,且在View的存储属性初始化阶段调用会有逻辑问题。
  2. 你使用了.forward升序排序,而Spina的punteggio值最高,需要用降序才能让它排在首位。

解决方案

方案1:用计算属性返回排序后的数组(推荐)

这种方式不会修改原@State数组,适合需要保留原始数据的场景:

struct HomeView: View {
    @State private var squadre: [Squadre] = Squadre.test()
    
    // 计算属性:返回按punteggio降序排列的数组
    var sortedSquadre: [Squadre] {
        squadre.sorted(using: [KeyPathComparator(\.punteggio, order: .reverse)])
    }
    
    var body: some View {
        List(sortedSquadre) { squadra in
            // 自定义列表行内容示例
            VStack(alignment: .leading) {
                Text(squadra.squadra)
                    .font(.headline)
                Text("积分:\(squadra.punti) | 评分:\(squadra.punteggio)")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

说明:sorted(using:)是返回新数组的非mutating方法,不会改变原squadre数组,每次原数组更新时会自动重新计算排序结果。

方案2:初始化时直接排序@State数组

如果不需要保留原始数组顺序,可以在初始化时直接完成排序:

struct HomeView: View {
    // 初始化时就按punteggio降序排列
    @State private var squadre: [Squadre] = Squadre.test().sorted(using: [KeyPathComparator(\.punteggio, order: .reverse)])
    
    var body: some View {
        List(squadre) { squadra in
            // 列表行内容
        }
    }
}

额外优化:修复Squadre结构体的潜在bug

你的Squadre初始化方法存在两个问题:

  1. 传入的diffreti、punti、punteggio参数完全没被使用,属于冗余参数。
  2. 整数除法导致punteggio计算错误(比如34/100会得到0,而不是0.34)。

优化后的结构体代码:

import Foundation

struct Squadre: Identifiable, Hashable {
    let id = UUID()
    let stagione: String
    let squadra: String
    let vinte: Int
    let pareggiate: Int
    let perse: Int
    let golfatti: Int
    let golsubiti: Int
    let diffreti: Int
    let punti: Int
    let punteggio: Double
    
    // 简化初始化方法,移除冗余参数
    init(stagione: String, squadra: String, vinte: Int, pareggiate: Int, perse: Int, golfatti: Int, golsubiti: Int) {
        self.stagione = stagione
        self.squadra = squadra
        self.vinte = vinte
        self.pareggiate = pareggiate
        self.perse = perse
        self.golfatti = golfatti
        self.golsubiti = golsubiti
        self.diffreti = golfatti - golsubiti
        self.punti = (vinte * 3) + pareggiate
        // 转成Double后再计算,避免整数除法错误
        self.punteggio = Double(punti) + (Double(golfatti)/100) + (Double(diffreti)/1000)
    }
    
    static func test() -> [Squadre] {
        // 调用简化后的初始化方法,无需传入计算参数
        [
            Squadre(stagione: "2023/2024", squadra: "Castello", vinte: 10, pareggiate: 7, perse: 4, golfatti: 34, golsubiti: 27),
            Squadre(stagione: "2023/2024", squadra: "Sole", vinte: 10, pareggiate: 7, perse: 4, golfatti: 34, golsubiti: 28),
            Squadre(stagione: "2023/2024", squadra: "Spina", vinte: 11, pareggiate: 6, perse: 4, golfatti: 34, golsubiti: 27)
        ]
    }    
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 06:42:48