代码之家  ›  专栏  ›  技术社区  ›  SBB

Javascript缩小或展平对象?

  •  2
  • SBB  · 技术社区  · 6 年前

    我有一个数据对象,它是动态的,来自一个数据库调用。如果记录包含 approval 细节,它将包含在我得到的对象中,否则它将被忽略。

    我的问题是,我有一个导出方法,它将对象转换为excel文件,但这只是使用对象的第一级,因此可能缺少批准数据。

    我试图找出如何展平或缩小对象,以便将所有键/值都带到父级。

    示例代码:

    // Current Data
    var obj = [{
        "toolSuite": "Enterprise Product",
        "toolStatus": "Active",
        "toolOwnerGroup": "PD",
        "toolTier": "1",
        "infoSec": "Yes",
        "sso": "?",
        "toolPortfolio": "Enterprise Product",
        "NeedByDate": "29-Jun-2018",
        "approvals": {
            "approval": { <--- Need to move all this data to the parent level
                "ApprovalID": "139",
                "TaskID": "232",
                "SubmissionDate": "2018-10-03T22:19:24.153",
                "WhoSubmitted": "Q1234",
                "Approver": "Q5678",
                "IsCanceled": "0",
                "ApproverFirst": "Bob",
                "ApproverLast": "Builder",
                "ApproverNTID": "bbuilder"
            }
        }
    }, {
        "toolSuite": "Enterprise Product",
        "toolStatus": "Active",
        "toolOwnerGroup": "PD",
        "toolTier": "1",
        "infoSec": "Yes",
        "sso": "?",
        "toolPortfolio": "Enterprise Product",
        "NeedByDate": "29-Jun-2018",
        "ApprovalID": "139"
    }]
    
    
    // Desired Output
    var obj = [{
        "toolSuite": "Enterprise Product",
        "toolStatus": "Active",
        "toolOwnerGroup": "PD",
        "toolTier": "1",
        "infoSec": "Yes",
        "sso": "?",
        "toolPortfolio": "Enterprise Product",
        "NeedByDate": "29-Jun-2018",
        "ApprovalID": "139",
        "TaskID": "232",
        "SubmissionDate": "2018-10-03T22:19:24.153",
        "WhoSubmitted": "Q1234",
        "Approver": "Q5678",
        "IsCanceled": "0",
        "ApproverFirst": "Bob",
        "ApproverLast": "Builder",
        "ApproverNTID": "bbuilder"
    
    }, {
        "toolSuite": "Enterprise Product",
        "toolStatus": "Active",
        "toolOwnerGroup": "PD",
        "toolTier": "1",
        "infoSec": "Yes",
        "sso": "?",
        "toolPortfolio": "Enterprise Product",
        "NeedByDate": "29-Jun-2018",
    }]
    

    在上面的代码中,第一个对象具有 approvals.approval 数据。我正在尝试将此数据带到父级。它不是一个数据数组,因此不会有重复的键。

    我目前正在使用 lodash 在我的其他项目,但我找不到任何东西,我可以轻松地运行这个通过做我需要的。

    reduce flatten ? 它 应该 但如果有什么办法,我可以指定一个深度说 3 它可以将这些数据移动到父级,这将是理想的。

    我应该用什么方法来处理这类对象?

    2 回复  |  直到 6 年前
        1
  •  3
  •   CertainPerformance    6 年前

    不需要图书馆,只需要传播或 Object.assign approval 对象,然后删除 approvals

    var obj=[{"toolSuite":"Enterprise Product","toolStatus":"Active","toolOwnerGroup":"PD","toolTier":"1","infoSec":"Yes","sso":"?","toolPortfolio":"Enterprise Product","NeedByDate":"29-Jun-2018","approvals":{"approval":{"ApprovalID":"139","TaskID":"232","SubmissionDate":"2018-10-03T22:19:24.153","WhoSubmitted":"Q1234","Approver":"Q5678","IsCanceled":"0","ApproverFirst":"Bob","ApproverLast":"Builder","ApproverNTID":"bbuilder"}}},{"toolSuite":"Enterprise Product","toolStatus":"Active","toolOwnerGroup":"PD","toolTier":"1","infoSec":"Yes","sso":"?","toolPortfolio":"Enterprise Product","NeedByDate":"29-Jun-2018","ApprovalID":"139"}];
    
    Object.assign(obj[0], obj[0].approvals.approval);
    delete obj[0].approvals;
    console.log(obj[0]);

    如果列表中有多个项目 obj approvals: { approval: { ... } } 需要传输的属性,然后使用循环:

    obj.forEach((object) => {
      const { approvals } = object;
      if (!approvals) return;
      Object.assign(object, approvals.approval);
      delete object.approvals;
    });
    

    我还建议你重新命名你的 目标 数组到其他对象,如果可能的话-它是一个数组,而不是一个普通对象,所以可以这样称呼它 arr

        2
  •  0
  •   Akrion    6 年前

    使用 lodash 这有点可读性(通过 mergeWith omit )像这样:

    var data = { "toolSuite": "Enterprise Product", "toolStatus": "Active", "toolOwnerGroup": "PD", "toolTier": "1", "infoSec": "Yes", "sso": "?", "toolPortfolio": "Enterprise Product", "NeedByDate": "29-Jun-2018", "approvals": { "approval": { "ApprovalID": "139", "TaskID": "232", "SubmissionDate": "2018-10-03T22:19:24.153", "WhoSubmitted": "Q1234", "Approver": "Q5678", "IsCanceled": "0", "ApproverFirst": "Bob", "ApproverLast": "Builder", "ApproverNTID": "bbuilder" } } }
    
    const result = _(data)
      .mergeWith(data.approvals.approval)
      .omit('approvals')
      .value()  
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

    如果有 data map 通过,因为您确实希望获得与输入相同数量的输出:

    var data = [{ "toolSuite": "Enterprise Product", "toolStatus": "Active", "toolOwnerGroup": "PD", "toolTier": "1", "infoSec": "Yes", "sso": "?", "toolPortfolio": "Enterprise Product", "NeedByDate": "29-Jun-2018", "approvals": { "approval": { "ApprovalID": "139", "TaskID": "232", "SubmissionDate": "2018-10-03T22:19:24.153", "WhoSubmitted": "Q1234", "Approver": "Q5678", "IsCanceled": "0", "ApproverFirst": "Bob", "ApproverLast": "Builder", "ApproverNTID": "bbuilder" } } }, { "toolSuite": "Enterprise Product", "toolStatus": "Active", "toolOwnerGroup": "PD", "toolTier": "1", "infoSec": "Yes", "sso": "?", "toolPortfolio": "Enterprise Product", "NeedByDate": "29-Jun-2018" }]
    
    const result = _.map(data, obj => _(obj)
       .mergeWith(_.get(obj,'approvals.approval'))
       .omit('approvals')
       .value())
    
    console.log(result)
    <