【问题标题】:Recursive replace in hierarchy层次结构中的递归替换
【发布时间】:2020-04-26 11:35:21
【问题描述】:

我有一棵 JSON 树喜欢 this Github link

如您所见,这棵树使用每个项目的formula 属性来计算其值。所以我需要计算几个节点或根节点的值。

您可以看到 PL6A,PL6B 是带有type = 1 的树的末端。所以我需要替换到树,所以PLVALUE 构造的formula 必须替换为ACVALUE

示例: PL10 公式必须替换为 (ACVALUE(PL6A)+ACVALUE(PL6B))+...

我该怎么做,谢谢你,抱歉英语不好

更新 我试过这段代码:

  for (let i = 0; i < accounts.length; i++) {
    const item = accounts[i];
    let { formula } = accounts[i];

    if (item.children.length && item.type === 2) {
      //Replace formula with full children formula
      item.children.forEach((child) => {
        if (formula.indexOf(child.code) > -1) {
          const fullInfoChild = accounts.find(
            (fullInfoItem) => _.trim(fullInfoItem._id) === _.trim(child._id)
          );

          formula = _.replace(
            formula,
            `PLVALUE(${child.code})`,
            `(${fullInfoChild.formula})`
          );
        }
      });
    } else {
      formula = item.formula;
    }
    accounts[i].formula = formula;
  }

结果,一些节点运行良好

        {
            "_id": "5cf6159f386f5942aabca347",
            "code": "PL10",
            "formula": "(ACVALUE(PL6A)+ACVALUE(PL6B))+(ACVALUE(PL9))+(ACVALUE(PL7B)+ACVALUE(PL7A))+(ACVALUE(PL8A)+ACVALUE(PL8B))+(ACVALUE(DSRGP))",
            "status": 1,
            "type": 2,
            "parents": [
                {
                    "_id": "5cf61756386f5942aabca365",
                    "code": "PL28",
                    "formula": "PLVALUE(PL10)+PLVALUE(PL15)",
                    "status": 1,
                    "type": 2
                }
            ],
            "children": [
                {
                    "_id": "5cf614f4386f5942aabca342",
                    "code": "PL6",
                    "formula": "ACVALUE(PL6A)+ACVALUE(PL6B)",
                    "status": 1,
                    "type": 2
                },
                {
                    "_id": "5cf6156a386f5942aabca346",
                    "code": "PL_DSRGP",
                    "formula": "ACVALUE(DSRGP)",
                    "status": 1,
                    "type": 2
                },
                {
                    "_id": "5cf6152f386f5942aabca345",
                    "code": "PL9",
                    "formula": "ACVALUE(PL9)",
                    "status": 1,
                    "type": 2
                },
                {
                    "_id": "5cf6150e386f5942aabca343",
                    "code": "PL7",
                    "formula": "ACVALUE(PL7B)+ACVALUE(PL7A)",
                    "status": 1,
                    "type": 2
                },
                {
                    "_id": "5cf6151e386f5942aabca344",
                    "code": "PL8",
                    "formula": "ACVALUE(PL8A)+ACVALUE(PL8B)",
                    "status": 1,
                    "type": 2
                }
            ],
            "totalCurrentYear": 0
        },

但如果我们提高了一些水平,它就不会像这个那样工作

        {
            "_id": "5cf8c78b4aafe73cb56ce424",
            "code": "PL30",
            "formula": "(((ACVALUE(PL6A)+ACVALUE(PL6B))+(ACVALUE(PL9))+(ACVALUE(PL7B)+ACVALUE(PL7A))+(ACVALUE(PL8A)+ACVALUE(PL8B))+(ACVALUE(DSRGP)))+((ACVALUE(511000)+ACVALUE(735013)+ACVALUE(511100))+(ACVALUE(511002)+ACVALUE(511101)+ACVALUE(554020)+ACVALUE(735015))+(ACVALUE(511003)+ACVALUE(511102)+ACVALUE(735016))+(ACVALUE(511004)+ACVALUE(554010)+ACVALUE(554021)+ACVALUE(735017)+ACVALUE(554030))))+(PLVALUE(PL23)+PLVALUE(PL24)+PLVALUE(PL25))",
            "status": 1,
            "type": 2,
            "children": [
                {
                    "_id": "5cf61756386f5942aabca365",
                    "code": "PL28",
                    "formula": "PLVALUE(PL10)+PLVALUE(PL15)",
                    "status": 1,
                    "type": 2
                },
                {
                    "_id": "5cf8c7bd4aafe73cb56ce426",
                    "code": "PL26",
                    "formula": "PLVALUE(PL23)+PLVALUE(PL24)+PLVALUE(PL25)",
                    "status": 1,
                    "type": 2
                }
            ],
        },

更新:将完整的 json 数据添加到 github 链接

【问题讨论】:

  • 请添加你的尝试
  • @NinaScholz 我已经更新了我的尝试

标签: javascript node.js json


【解决方案1】:

您可以收集对code/formula 的引用以及替换和迭代公式以获取值的公式。

var data = [{ _id: "5cf8c78b4aafe73cb56ce424", code: "PL30", formula: "PLVALUE(PL28)+PLVALUE(PL26)", status: 1, type: 2, children: [{ _id: "5cf61756386f5942aabca365", code: "PL28", formula: "PLVALUE(PL10)+PLVALUE(PL15)", status: 1, type: 2 }, { _id: "5cf8c7bd4aafe73cb56ce426", code: "PL26", formula: "PLVALUE(PL23)+PLVALUE(PL24)+PLVALUE(PL25)", status: 1, type: 2 }] }, { _id: "5cf61756386f5942aabca365", code: "PL28", formula: "PLVALUE(PL10)+PLVALUE(PL15)", status: 1, type: 2, children: [{ _id: "5cf6159f386f5942aabca347", code: "PL10", formula: "PLVALUE(PL6)+PLVALUE(PL9)+PLVALUE(PL7)+PLVALUE(PL8)+PLVALUE(PL_DSRGP)", status: 1, type: 2 }, { _id: "5cf61741386f5942aabca364", code: "PL15", formula: "PLVALUE(PL11)+PLVALUE(PL12)+PLVALUE(PL13)+PLVALUE(PL14)", status: 1, type: 2 }], totalCurrentYear: 0 }, { _id: "5cf6159f386f5942aabca347", code: "PL10", formula: "PLVALUE(PL6)+PLVALUE(PL9)+PLVALUE(PL7)+PLVALUE(PL8)+PLVALUE(PL_DSRGP)", status: 1, type: 2, children: [{ _id: "5cf614f4386f5942aabca342", code: "PL6", formula: "ACVALUE(PL6A)+ACVALUE(PL6B)", status: 1, type: 2 }, { _id: "5cf6156a386f5942aabca346", code: "PL_DSRGP", formula: "ACVALUE(DSRGP)", status: 1, type: 2 }, { _id: "5cf6152f386f5942aabca345", code: "PL9", formula: "ACVALUE(PL9)", status: 1, type: 2 }, { _id: "5cf6150e386f5942aabca343", code: "PL7", formula: "ACVALUE(PL7B)+ACVALUE(PL7A)", status: 1, type: 2 }, { _id: "5cf6151e386f5942aabca344", code: "PL8", formula: "ACVALUE(PL8A)+ACVALUE(PL8B)", status: 1, type: 2 }] }, { _id: "5cf614f4386f5942aabca342", code: "PL6", formula: "ACVALUE(PL6A)+ACVALUE(PL6B)", status: 1, type: 2, children: [{ _id: "5cf61869386f5942aabca368", code: "PL6A", type: 1, status: 1 }, { _id: "5cf6187f386f5942aabca36a", code: "PL6B", type: 1, status: 1 }], totalCurrentYear: 0 }],
    replace = (formula, values) => formula.replace(/PLVALUE\(([^\)]+)\)/g, (full, group) => group in values
        ? `(${values[group].object[values[group].key]})`
        : full
    ),
    getNestedValues = (r, object) => {
        r.values[object.code] = { object, key: object.type === 1 ? 'code' : 'formula' };
        if (object.formula?.includes('PLVALUE')) r.formulas.push(object);
        if (object.children) object.children.reduce(getNestedValues, r);
        return r;
    },
    { values, formulas } = data.reduce(getNestedValues, { values: {}, formulas: [] });

// while (formulas.length) { // only if all targets are known
    let i = formulas.length;
    while (i--) {
        let s = replace(formulas[i].formula, values);
        if (s === formulas[i].formula) continue;
        formulas[i].formula = s;
        formulas.splice(i, 1);
    }
// } // only if all targets are known

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢 Nina,但由于服务器崩溃 link,我仍然无法测试您的代码。不知道为什么可以在sn-p中运行
  • object.formula?.includes('PLVALUE') 替换为object.formula &amp;&amp; object.formula.includes('PLVALUE'),因为看起来optional chaining operator ?. 没有实现。
猜你喜欢
  • 1970-01-01
  • 2013-11-22
  • 2017-02-04
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-25
  • 2012-01-27
相关资源
最近更新 更多