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

ServiceNow递归获取经理下属:修正JSON输出为嵌套对象

问题描述

在ServiceNow中实现场景:为指定经理的所有直接/间接下属生成嵌套对象结构的JSON。当前递归函数输出为数组形式:

[
  "user1", ["user3", ["user4"]], 
  "user2", ["user5", ["user6","user7"], "user8", ["user9"]]
]

期望输出为嵌套对象形式:

{
  "user1": {
    "user3": ["user4"]
  },
  "user2": {
    "user5": ["user6", "user7"],
    "user8": ["user9"]
  }
}

现有实现代码:

function reportee(userID) {
  var userGr = new GlideRecord('sys_user');
  userGr.addQuery('manager', userID);
  userGr.query();

  var reporteeArr = [];
  while (userGr.next()) {
    if (reporteeArr.indexOf(userGr.name.toString()) == -1) {
      reporteeArr.push(userGr.name.toString()); //We will push the reportee name if it's not already in array
      var subReportee = reportee(userGr.sys_id);
      if (subReportee.length > 0) {
        reporteeArr.push(subReportee); // learn how to concatenate
      }
    }
  }
  return reporteeArr;
}

var userID = 'd6ea959c471311103c8dda97436d4370'; // sys_id of users to find his/her reportees
var reportees = reportee(userID);
gs.info(JSON.stringify(reportees));
修正方案

修改递归函数的返回逻辑,将交替数组结构转换为符合期望的嵌套对象/数组混合结构:

function reportee(userID) {
  var userGr = new GlideRecord('sys_user');
  userGr.addQuery('manager', userID);
  userGr.query();

  const children = [];
  while (userGr.next()) {
    const userName = userGr.name.toString();
    const subReportee = reportee(userGr.sys_id);
    
    // 判断子结构是否有内容:数组长度>0 或 对象有键值对
    const hasSubordinates = Array.isArray(subReportee) 
      ? subReportee.length > 0 
      : Object.keys(subReportee).length > 0;

    children.push(userName);
    // 仅当子结构有内容时,才将其加入临时数组
    if (hasSubordinates) {
      children.push(subReportee);
    }
  }

  // 处理临时数组,返回对应结构
  if (children.length === 0) {
    return {};
  }

  // 若所有元素都是字符串,说明是无下属的叶子节点,返回数组
  const allLeaves = children.every(item => typeof item === 'string');
  if (allLeaves) {
    return children;
  }

  // 否则转换为嵌套对象
  const resultObj = {};
  for (let i = 0; i < children.length; i += 2) {
    const key = children[i];
    const value = children[i + 1];
    resultObj[key] = value;
  }
  return resultObj;
}

var userID = 'd6ea959c471311103c8dda97436d4370';
var reportees = reportee(userID);
gs.info(JSON.stringify(reportees));

关键改动说明

  1. 临时数组收集结构:用children数组临时存储下属名称及其子结构,替代原有的直接结果数组。
  2. 子结构判断逻辑:递归调用后,判断子结构是否包含有效内容,仅当有下属时才将子结构加入临时数组。
  3. 动态返回结构:
    • 若临时数组为空,返回空对象(表示当前用户无下属)。
    • 若数组全为字符串(都是无下属的叶子节点),返回数组。
    • 若数组是交替的名称和子结构,转换为键值对对象,实现嵌套结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:15:30