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

Swift 4:如何统计字符串数组元素在字符串/字符串数组中的出现次数?

看起来你正在做一个很有意思的圣经数据统计项目!我来帮你解决名字统计的问题,分步骤来:

第一步:先整理你的名字数组

你的names数组当前是按换行分割,但原字符串里其实是空格分隔的,可能会产生空字符串,先处理成干净的数组:

let nameString = """ Abigail Ada Ahlai Angel Anna """
// 按空白(空格+换行)分割,过滤空字符串,得到干净的名字数组
let names = nameString.components(separatedBy: .whitespacesAndNewlines)
    .filter { !$0.isEmpty }
// 如果需要忽略大小写匹配(比如经文里的"abigail"也要统计),可以提前转成小写的Set(Set查询效率更高)
let lowercasedNameSet = Set(names.map { $0.lowercased() })
第二步:统计单个字符串中的名字出现次数

要准确统计,最好用正则匹配完整单词,避免把"Anna"误匹配到"Annabelle"这种部分重合的词里。这里写一个可复用的函数:

import Foundation // 正则需要依赖Foundation框架

func countNameOccurrences(in text: String, names: [String], caseInsensitive: Bool = true) -> [String: Int] {
    var counts: [String: Int] = [:]
    let processedText = caseInsensitive ? text.lowercased() : text
    
    for name in names {
        let targetName = caseInsensitive ? name.lowercased() : name
        // 转义名字里的特殊字符(比如如果名字包含.或者?),然后用\b匹配单词边界
        let regexPattern = "\\b\(NSRegularExpression.escapedPattern(for: targetName))\\b"
        
        guard let regex = try? NSRegularExpression(pattern: regexPattern) else {
            counts[name] = 0
            continue
        }
        
        // 统计当前名字的匹配次数
        let matchCount = regex.numberOfMatches(
            in: processedText,
            range: NSRange(processedText.startIndex..., in: processedText)
        )
        counts[name] = matchCount
    }
    return counts
}
第三步:统计字符串数组(所有经文)中的名字出现次数

你需要一个全局计数器,遍历所有verse的文本,累加每个名字的出现次数。结合你的现有代码修改如下:

// 初始化全局统计字典,记录每个名字的总出现次数
var totalNameCounts: [String: Int] = [:]

for chapter in genesis!.chapters {
    for verse in chapter.verses {
        // 从verse字典中提取经文文本(你的verse是["1":"经文内容"]结构,取第一个值即可)
        guard let verseText = verse.values.first else {
            continue // 如果没有文本就跳过当前verse
        }
        
        // 统计当前经文里的名字次数
        let currentVerseCounts = countNameOccurrences(in: verseText, names: names)
        
        // 累加到全局统计字典
        for (name, count) in currentVerseCounts {
            totalNameCounts[name] = (totalNameCounts[name] ?? 0) + count
        }
    }
}

// 最后可以按出现次数从高到低排序,拿到提及最多的名字
let sortedNameCounts = totalNameCounts.sorted { $0.value > $1.value }
if let topName = sortedNameCounts.first {
    print("提及最多的名字:\(topName.key),共出现\(topName.value)次")
}
额外优化点
  • 预编译正则表达式:如果名字数量很多,每次循环创建正则会影响效率,可以提前把所有名字的正则编译好,存在字典里复用。
  • 处理名字变体:圣经里有些名字可能有不同拼写(比如"Abraham"和"Abram"),如果需要合并统计,可以额外维护一个别名映射字典。
  • 批量统计:如果想一次性处理所有经文文本,可以先把所有verse的文本收集成数组,再调用批量统计的函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:17:18