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

SwiftUI自动生成按首字母与词长统计的表格问题

解决方案:结构化数据预处理 + 动态表格生成

针对你的需求,核心思路是先把单词数组预处理成结构化的统计数据,再基于这些数据动态生成表格,既能解决空值单元格的问题,也能让代码更简洁易维护。

步骤1:预处理统计数据

通过计算属性生成以下核心数据:

  • 所有唯一首字母(大写排序)
  • 完整的词长范围(覆盖4-15,补全缺失长度保证行连续)
  • 统计字典:记录每个(词长, 首字母)对应的单词数量
  • 行求和:每个词长下的总单词数
  • 列求和:每个首字母下的总单词数

步骤2:动态生成表格

用Grid(iOS 16+)构建表格,遍历预处理后的长度和首字母,空值直接显示0。

完整代码实现

struct ContentView: View {
    let words: [String] = ["deed", "denote", "donut", "eden", "ended", "heeded", "hood"]
    // 固定长度范围4-15
    private let lengthRange = 4...15
    
    // 提取唯一首字母(大写排序)
    private var uniqueLetters: [String] {
        Set(words.map { String($0.first!).uppercased() })
            .sorted()
    }
    
    // 统计(长度, 首字母)对应的单词数量,补全缺失长度
    private var wordCountDict: [Int: [String: Int]] {
        var dict: [Int: [String: Int]] = [:]
        for word in words {
            let length = word.count
            let letter = String(word.first!).uppercased()
            if dict[length] == nil { dict[length] = [:] }
            dict[length]![letter] = (dict[length]![letter] ?? 0) + 1
        }
        // 补全长度范围内所有缺失的长度
        for length in lengthRange {
            dict[length] = dict[length] ?? [:]
        }
        // 按长度排序后转成有序字典
        return dict.sorted(by: { $0.key < $1.key })
            .reduce(into: [Int: [String: Int]]()) { $0[$1.key] = $1.value }
    }
    
    // 行求和:每个长度的总单词数
    private var rowTotals: [Int: Int] {
        wordCountDict.mapValues { letterCounts in
            letterCounts.values.reduce(0, +)
        }
    }
    
    // 列求和:每个首字母的总单词数
    private var columnTotals: [String: Int] {
        var totals: [String: Int] = [:]
        for letter in uniqueLetters {
            totals[letter] = wordCountDict.values.reduce(0) { $0 + ($1[letter] ?? 0) }
        }
        return totals
    }
    
    var body: some View {
        Form {
            // 表头行:空单元格 + 首字母 + 总计
            GridRow {
                Text("").bold()
                ForEach(uniqueLetters, id: \.self) { letter in
                    Text(letter).bold()
                        .frame(maxWidth: .infinity)
                }
                Text("总计").bold()
                    .frame(maxWidth: .infinity)
            }
            
            // 数据行:长度 + 各首字母计数 + 行总计
            ForEach(lengthRange.filter { rowTotals[$0] != nil || wordCountDict[$0]!.values.contains { $0 > 0 } }, id: \.self) { length in
                GridRow {
                    Text("\(length)").bold()
                    ForEach(uniqueLetters, id: \.self) { letter in
                        Text("\(wordCountDict[length]![letter] ?? 0)")
                            .frame(maxWidth: .infinity)
                    }
                    Text("\(rowTotals[length] ?? 0)").bold()
                        .frame(maxWidth: .infinity)
                }
            }
            
            // 总计行:总计 + 各首字母总计 + 总和
            GridRow {
                Text("总计").bold()
                ForEach(uniqueLetters, id: \.self) { letter in
                    Text("\(columnTotals[letter] ?? 0)").bold()
                        .frame(maxWidth: .infinity)
                }
                Text("\(words.count)").bold()
                    .frame(maxWidth: .infinity)
            }
        }
        .gridStyle(.bordered) // 可选:给表格添加边框
    }
}

关键细节说明

  1. 空值处理:通过wordCountDict[length]![letter] ?? 0将空值转为0,保证每个单元格都有内容
  2. 动态适配:uniqueLetters自动提取当前单词数组的首字母,无需硬编码;长度范围固定4-15,自动补全缺失长度
  3. 代码简洁性:统计逻辑集中在计算属性中,UI部分仅需遍历预处理后的数据,避免重复的分组过滤代码
  4. 扩展性:调整长度范围或首字母数量时,只需修改lengthRange或相关统计逻辑即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:41:43