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

Swift中结合字典的Repeat-While循环实现输入向下匹配最近键问题排查

问题原因

  • repeat-while循环逻辑完全颠倒:你设置的循环继续条件是correctInput == true,但你的需求是没找到匹配键的时候继续循环,同时你在循环体内第一遍执行就直接return input,不管有没有匹配到都直接返回,所以循环永远只会执行一次
  • checkKey函数逻辑错误:你传入了score参数但实际判断用的是全局变量input,参数没有起到任何作用
  • Double精度问题:逐次减0.1的操作会导致浮点数精度丢失,比如运算后可能出现12.4000000000001这类值,永远无法和字典里的12.4匹配成功
  • 执行效率低:逐次递减匹配的时间复杂度很高,如果输入值和目标匹配值差距很大,会浪费大量算力

修复方案

更稳妥的实现方式是先把字典的所有键做降序排序,直接遍历一次排序后的键,找到第一个小于等于输入值的键即可,完全不需要循环递减:

struct FitnessScore {
    static let powerThrow = [
        12.50: 100,
        12.40: 99,
        12.20: 98,
        12.10: 97,
        11.90: 96,
        11.80: 95,
        11.60: 94,
        11.50: 93,
        11.30: 92,
        11.20: 91,
        11.00: 90,
        10.90: 89,
        10.70: 88,
        10.60: 87,
        10.40: 86,
        10.30: 85,
        10.10: 84,
        10.00: 83,
        9.80: 82 ]
}

let dict = FitnessScore.powerThrow
let input = 19.30

// 先对所有键做降序排序
let sortedKeys = dict.keys.sorted(by: >)
var finalInput: Double?

// 遍历找第一个小于等于输入值的键
for key in sortedKeys {
    if key <= input {
        finalInput = key
        break
    }
}

if let final = finalInput {
    print("your input score rounded down to \(final), corresponding score is \(dict[final]!)")
} else {
    print("input value is lower than all available keys")
}

如果你一定要保留repeat-while的写法,修复后的代码如下:

let dict = FitnessScore.powerThrow
var input = 19.30
var correctInput = false

func checkKey(score: Double) -> Bool {
    for (key, _) in dict {
        // 修复为用传入的score做判断,同时加精度容错
        if abs(key - score) < 0.001 {
            return true
        }
    }
    return false
}

func getFinalInput() -> Double {
    // 先判断初始值是否匹配
    correctInput = checkKey(score: input)
    repeat {
        if !correctInput {
            input -= 0.1
            correctInput = checkKey(score: input)
            print("this is the new input value: \(input)")
            print("this is the new condition: \(correctInput)")
        }
    } while !correctInput // 没找到就继续循环
    return input
}

print("your input score rounded down to \(getFinalInput())")

执行结果

输入19.30时,输出的匹配值为12.5,对应分数100,符合向下取最接近匹配键的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:06:03