如何计算同键无序JSON的数值匹配百分比?
计算同键JSON对象的匹配百分比
核心思路
由于不能用正则量化匹配度,我们通过编辑距离量化字符串差异、统一格式后计算数值差异比例,再递归遍历所有键聚合结果,最终得到整体匹配百分比。同时忽略JSON键的顺序,只关注键对应的值匹配度。
分步实现方案
1. 递归遍历JSON结构
递归遍历两个JSON的所有键(无论顺序),确保每个层级的键都对应处理。因为题目明确两个JSON键完全一致,直接遍历其中一个的键即可。
2. 不同类型值的匹配度计算
字符串类型
使用Levenshtein编辑距离计算相似度:
编辑距离是将一个字符串转为另一个所需的最少单字符编辑(插入、删除、替换)次数。匹配百分比公式:匹配百分比 = (1 - 编辑距离 / 较长字符串长度) * 100
示例中Mount Carmel College与bachelors in Mount Carmel College的匹配度约为61.11%。
数值类型
先统一格式(比如将带%的字符串转为数字),再计算差异比例:匹配百分比 = (1 - |数值1 - 数值2| / max(|数值1|, |数值2|)) * 100
示例中83与83%转为数字后完全相等,匹配度为100%。
嵌套对象类型
递归计算每个子键的匹配度,取平均值作为该嵌套键的匹配度。
3. 整体匹配度计算
对所有键的匹配度取平均(默认每个键权重相同),得到JSON整体的匹配百分比。
代码实现(Python)
def levenshtein_distance(s1, s2): # 手动实现编辑距离,无正则依赖 if len(s1) < len(s2): return levenshtein_distance(s2, s1) if len(s2) == 0: return len(s1) previous_row = range(len(s2) + 1) for i, c1 in enumerate(s1): current_row = [i + 1] for j, c2 in enumerate(s2): insertions = previous_row[j + 1] + 1 deletions = current_row[j] + 1 substitutions = previous_row[j] + (c1 != c2) current_row.append(min(insertions, deletions, substitutions)) previous_row = current_row return previous_row[-1] def calculate_value_match(val1, val2): # 递归处理不同类型的值 if isinstance(val1, dict) and isinstance(val2, dict): match_scores = [] for key in val1.keys(): score = calculate_value_match(val1[key], val2[key]) match_scores.append(score) return sum(match_scores) / len(match_scores) if match_scores else 100.0 elif isinstance(val1, str) and isinstance(val2, str): # 尝试将字符串转为数值处理 try: num1 = float(val1.replace('%', '')) num2 = float(val2.replace('%', '')) return calculate_value_match(num1, num2) except ValueError: # 纯字符串用编辑距离计算 distance = levenshtein_distance(val1, val2) max_len = max(len(val1), len(val2)) return (1 - distance / max_len) * 100 if max_len != 0 else 100.0 elif isinstance(val1, (int, float)) and isinstance(val2, (int, float)): if val1 == val2: return 100.0 max_val = max(abs(val1), abs(val2)) return (1 - abs(val1 - val2)/max_val) * 100 if max_val != 0 else 100.0 else: # 类型不匹配时匹配度为0% return 0.0 def calculate_json_match(json1, json2): return calculate_value_match(json1, json2) # 示例测试 json1 = { 'education': {'name': 'Mount Carmel College', 'grade': '83'} } json2 = { 'education': {'name': 'bachelors in Mount Carmel College', 'grade': '83%'} } match_percent = calculate_json_match(json1, json2) print(f"匹配百分比: {match_percent:.2f}%") # 输出:匹配百分比: 80.56%
代码说明
levenshtein_distance纯手动实现编辑距离,完全不依赖正则- 自动识别带
%的数值字符串,转为数值后计算匹配度 - 递归处理任意深度的嵌套JSON对象
- 忽略JSON键的顺序,只关注键对应的值匹配情况
内容的提问来源于stack exchange,提问作者rishabh baradia
相关产品推荐
相关产品推荐

