发布于2026-07-07 阅读(0)
扫一扫,手机访问
如果你开发过电商后台、物流系统或者任何需要处理实物重量的应用,大概率会遇到这样一个场景:用户上传的数据里,有的写了“1 Kg”,有的写了“300 g”,甚至还有“1.5Kg”这种不带空格的。你以为拿sort()一把梭就能搞定?结果排序出来,“1 Kg”排到了“20 g”前面——按字典序,“1”确实小于“2”,但20克才0.02千克,本该排第一才对。这就是典型的单位混用陷阱。
解决思路其实很朴素:先把所有重量统一到一个基准单位(推荐克),然后按数值排序,最后再恢复成原始字符串格式输出。下面给出一段健壮且可扩展的 PHP 实现,直接看代码:
$weights = ['1 Kg', '300 g', '1.5 Kg', '20 g', '5 Kg'];// 构建归一化映射:数值(单位:克) → 原始字符串$normalized = [];foreach ($weights as $str) { $str = trim($str); // 使用正则安全提取数值和单位(支持空格、大小写) if (preg_match('/^([\d.]+)\s*([gG]|[kK][gG])$/', $str, $matches)) { $value = (float)$matches[1]; $unit = strtoupper($matches[2]); $grams = $unit === 'G' ? $value : $value * 1000; // 'G' → 克;'KG' → 千克转克 $normalized[$grams] = $str; }}// 按克为单位的数值升序排序(保留原始字符串)ksort($normalized);$sorted_weights = array_values($normalized);print_r($sorted_weights);// 输出:Array ( [0] => 20 g [1] => 300 g [2] => 1 Kg [3] => 1.5 Kg [4] => 5 Kg )
几个值得留意的设计细节:
preg_match 而不是 strpos 或 explode,是为了避免误判——比如“100g”没有空格,“Kg”大小写混写,正则都能一把兜住;trim() 看似小动作,实则可以防止用户不经意敲出的首尾空格干扰解析;float,确保像“1.5”这样的小数不会丢失精度;ksort() 按键升序,再用 array_values() 重置索引,得到的就是干净的标准索引数组。需要你额外留意的几个点:
else 分支记录警告或者抛出异常,否则静默跳过容易埋坑;usort() 配合匿名函数做原地排序。理由很简单:每次比较都要重新解析单位,性能差,而且逻辑分散,不利于后期维护。说到底,这类问题的核心就是“单位归一化 + 键值映射排序”。把不同单位的度量值先换算成同一把尺子,再排序,再还原——思路清晰、代码简洁、可维护性也高。下次遇到混用单位的排序需求,不妨试试这个套路。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8