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

字符串格式JSONPath按括号内字母与数值混合排序的最佳实现方案

实现思路
  • 第一步:预解析所有JSONPath为结构化的节点列表
    用正则匹配提取所有[xxx]中的内容,每个内容对应一个节点:
    • 若内容以单/双引号包裹,去掉引号后存为字符串类型节点
    • 若内容为纯数字,直接转为整型数值存为数字类型节点
      提前解析的好处是避免排序过程中重复解析字符串,性能提升明显,尤其当待排序列表规模较大时。
  • 第二步:实现自定义比较逻辑
    两个JSONPath做比较时,按顺序逐个比对对应位置的节点:
    1. 若当前位置两个节点都是字符串类型,直接按字母序比较
    2. 若当前位置两个节点都是数字类型,按数值大小比较
    3. 若前面所有节点都相等,节点数更少的JSONPath排在前面
Java实现示例
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class JsonPathSorter {
    // 解析单个JSONPath为节点列表
    private static List<Comparable<?>> parseJsonPath(String jsonPath) {
        List<Comparable<?>> nodes = new ArrayList<>();
        // 匹配所有[]中的内容
        Pattern pattern = Pattern.compile("\\[(.*?)]");
        Matcher matcher = pattern.matcher(jsonPath);
        while (matcher.find()) {
            String content = matcher.group(1);
            // 判断是字符串节点还是数字节点
            if (content.startsWith("'") || content.startsWith("\"")) {
                // 去掉前后引号
                nodes.add(content.substring(1, content.length() - 1));
            } else {
                // 转成整数,数字范围大的话可以换Long
                nodes.add(Integer.parseInt(content));
            }
        }
        return nodes;
    }

    public static void main(String[] args) {
        List<String> jsonPathList = new ArrayList<>();
        // 此处填入你的JSONPath列表
        jsonPathList.add("\"$['book'][10]['title']\"");
        jsonPathList.add("\"$['book'][2]['title']\"");
        jsonPathList.add("\"$['movie']['series'][10]['title']\"");
        jsonPathList.add("\"$['movie']['series'][2]['title']\"");

        // 预解析所有JSONPath,存为原字符串和节点列表的映射
        Map<String, List<Comparable<?>>> pathNodeMap = jsonPathList.stream()
                .collect(Collectors.toMap(Function.identity(), JsonPathSorter::parseJsonPath));

        // 自定义排序
        Collections.sort(jsonPathList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                List<Comparable<?>> nodes1 = pathNodeMap.get(o1);
                List<Comparable<?>> nodes2 = pathNodeMap.get(o2);
                int minLen = Math.min(nodes1.size(), nodes2.size());
                for (int i = 0; i < minLen; i++) {
                    Comparable n1 = nodes1.get(i);
                    Comparable n2 = nodes2.get(i);
                    // 同类型直接比较
                    if (n1.getClass().equals(n2.getClass())) {
                        int cmp = n1.compareTo(n2);
                        if (cmp != 0) {
                            return cmp;
                        }
                    } else {
                        // 不同类型可自定义排序规则,此处示例数字排在字符串前面
                        return n1 instanceof Integer ? -1 : 1;
                    }
                }
                // 前面节点都相等,短的排前面
                return Integer.compare(nodes1.size(), nodes2.size());
            }
        });

        // 输出排序结果
        jsonPathList.forEach(System.out::println);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:57:01