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

如何在JavaScript中将含children数组的嵌套对象转为单一对象

扁平化含children的嵌套对象为单一对象

我需要处理一个JavaScript嵌套对象,每个节点都带有children数组(每个父节点固定有2个子节点,层级嵌套),目标是把整个结构转换成一个单一对象(而非数组)。

示例嵌套对象

const par = {
    id: 1,
    name: "parent",
    children: [{
        id: 2,
        name: "child 1",
        children:[{
            id: 4,
            name: "child 3",
            children: [],
        },{
            id: 5,
            name: "child 4 ",
        }]
    },{
        id: 3,
        name: "child 2",
        children: [{
            id: 6,
            name: "child 5",
        },{
            id: 7,
            name: "child 6",
            children: []
        }]
    }]
}

现有函数的问题

我之前找到一个扁平化函数,但它返回的是数组,不符合我要单一对象的需求:

function flat(r, a) {
    let b = {};
    Object.keys(a).forEach(function (k) {
        if (k !== 'children') {
            b[k] = a[k];
        }
    });
    r.push(b);
    if (Array.isArray(a.children)) {
        b.children = a.children.map(function (a) { return a.id;});
        return a.children.reduce(flat, r);
    }
    return r;
}

解决方案

可以修改递归逻辑,把每个节点以id为键存入结果对象中,同时保留子节点的id列表(保持结构关联):

function flattenToObject(node, result = {}) {
    // 复制当前节点属性,将children转为子节点id数组(无children则设为空数组)
    const nodeData = { ...node };
    nodeData.children = Array.isArray(nodeData.children) 
        ? nodeData.children.map(child => child.id) 
        : [];
    
    // 以id为键存入结果对象
    result[node.id] = nodeData;
    
    // 递归处理所有子节点
    if (Array.isArray(node.children)) {
        node.children.forEach(child => flattenToObject(child, result));
    }
    
    return result;
}

// 使用示例
const flattenedObj = flattenToObject(par);
console.log(flattenedObj);

输出结果示例

最终得到的单一对象结构如下:

{
  1: { id: 1, name: "parent", children: [2, 3] },
  2: { id: 2, name: "child 1", children: [4, 5] },
  3: { id: 3, name: "child 2", children: [6, 7] },
  4: { id: 4, name: "child 3", children: [] },
  5: { id: 5, name: "child 4 ", children: [] },
  6: { id: 6, name: "child 5", children: [] },
  7: { id: 7, name: "child 6", children: [] }
}

如果不需要保留children字段,仅平铺所有节点信息,可简化逻辑:

function flattenToObject(node, result = {}) {
    // 剔除children属性,保留其他节点信息
    const { children, ...nodeData } = node;
    result[node.id] = nodeData;
    
    // 递归处理子节点
    if (Array.isArray(children)) {
        children.forEach(child => flattenToObject(child, result));
    }
    
    return result;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:50:30