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

如何按指定路径过滤深层嵌套map内容,保留目标字段?

Clojure 原生实现方案

以下实现无第三方依赖,完美适配嵌套列表场景、公共前缀路径筛选需求:

(defn select-paths [m paths]
  (letfn [(process [node path-prefix]
            (cond
              ;; 处理序列/列表节点,对每个元素复用当前路径规则筛选
              (sequential? node)
              (mapv #(process % path-prefix) node)
              ;; 处理map节点,按路径前缀匹配筛选键
              (map? node)
              (->> node
                   (keep (fn [[k v]]
                           (let [new-prefix (conj path-prefix k)]
                             ;; 仅保留存在匹配路径前缀的键
                             (when (some #(= (take (count new-prefix) %) new-prefix) paths)
                               (if (contains? (set paths) new-prefix)
                                 ;; 当前路径为完整指定路径,直接保留值
                                 [k v]
                                 ;; 当前路径为前缀,递归处理下一级
                                 [k (process v new-prefix)])))))
                   (into {}))
              ;; 基础类型节点直接返回
              :else node))]
    (process m [])))

测试验证

用你提供的示例数据调用,返回结果和预期完全一致:

(def m {:a 1
        :b {:c [{:d 1 :e 1} 
                {:d 2 :e 2}]
            :f 1}
        :g {:h {:i 4 :j [1 2 3]}}})

(select-paths m [[:a] [:b :c :e] [:b :f] [:g :h :i]])
;; => {:a 1, :b {:c [{:e 1} {:e 2}], :f 1}, :g {:h {:i 4}}}

Java Jackson 实现方案

如果是Java生态处理JSON场景,可基于Jackson的JsonNode实现相同逻辑:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class PathSelector {
    public JsonNode selectPaths(JsonNode root, List<List<String>> paths) {
        return process(root, new ArrayList<>(), paths);
    }

    private JsonNode process(JsonNode node, List<String> currentPrefix, List<List<String>> paths) {
        // 处理数组节点
        if (node.isArray()) {
            ArrayNode resultArr = JsonNodeFactory.instance.arrayNode();
            for (JsonNode item : node) {
                resultArr.add(process(item, new ArrayList<>(currentPrefix), paths));
            }
            return resultArr;
        }
        // 处理对象节点
        if (node.isObject()) {
            ObjectNode resultObj = JsonNodeFactory.instance.objectNode();
            Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> field = fields.next();
                List<String> newPrefix = new ArrayList<>(currentPrefix);
                newPrefix.add(field.getKey());
                // 检查是否有路径匹配当前前缀
                boolean hasMatch = paths.stream()
                        .anyMatch(path -> path.size() >= newPrefix.size()
                                && path.subList(0, newPrefix.size()).equals(newPrefix));
                if (hasMatch) {
                    if (paths.contains(newPrefix)) {
                        resultObj.set(field.getKey(), field.getValue());
                    } else {
                        resultObj.set(field.getKey(), process(field.getValue(), newPrefix, paths));
                    }
                }
            }
            return resultObj;
        }
        // 基础类型直接返回
        return node;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:21:04