【问题标题】:How to update JSON object with particular condition如何更新具有特定条件的 JSON 对象
【发布时间】:2018-07-20 07:45:22
【问题描述】:

我有两个 JSON 文件,第一个是 origin.json,第二个是 newData.json

我想根据NewData 更新Origin 的子值,但更新必须只影响userAgentsnewData.json 中存在的项目。

以下代码展示了我需要转换的数据:

var originData = {
    "userAgents": [
        "Chrome",
        "Safari"
    ],
    "tests": [
        {
            "name": "a",
            "errs": []
        },
        {
            "name": "b",
            "errs": [
                {
                    "userAgent": "Chrome"
                },
                {
                    "userAgent": "Safari"
                }
            ]
        }
    ]
};

var newData = {
    "userAgents": [
        "Chrome"
    ],
    "tests": [
        {
            "name": "a",
            "errs": []
        },
        {
            "name": "b",
            "errs": []
        }
    ]
};

originData.tests.forEach(function (originItem) {
    newData.tests.forEach(function (newItem) {
        if (newItem.name === originItem.name) {
            originItem.errs = newItem.errs
        }
    })


});


console.log(originData);

在这种情况下,结果是这样的:

{
    "userAgents": [
        "Chrome",
        "Safari"
    ],
    "tests": [
        {
            "name": "a",
            "errs": []
        },
        {
            "name": "b",
            "errs": []
        }
    ]
}

但是这个结果是错误的,正确的结果应该是这样的:

{
    "userAgents": [
        "Chrome",
        "Safari"
    ],
    "tests": [
        {
            "name": "a",
            "errs": []
        },
        {
            "name": "b",
            "errs": [
                {
                    "userAgent": "Safari"
                }
            ]
        }
    ]
}

你知道如何使用 Node.js 得到这个结果吗?

【问题讨论】:

标签: javascript json node.js javascript-objects


【解决方案1】:

使用以下代码:

const originData = {
  "userAgents": [
      "Chrome",
      "Safari"
  ],
  "tests": [
    {
      "name": "a",
      "errs": []
    },
    {
      "name": "b",
      "errs": [
        {
          "userAgent": "Chrome"
        },
        {
          "userAgent": "Safari"
        }
      ]
    }
  ]
};

const newData = {
  "userAgents": [
      "Chrome"
  ],
  "tests": [
    {
      "name": "a",
      "errs": []
    },
    {
      "name": "b",
      "errs": [
        {
          "userAgent": "Safari"
        }
      ]
    }
  ]
};

originData.tests.forEach(originItem => {
  const newEl = newData.tests.find(ne => ne.name === originItem.name);
  originItem.errs = originItem.errs.filter(e => newData.userAgents.includes(e.userAgent) || (newEl && -1 !== newEl.errs.findIndex(nee => nee.userAgent === e.userAgent)));
});


console.log(originData);

【讨论】:

  • 这个脚本在newData 上没有正确的结果我把`[{"userAgent": "Chrome"}]` 的数组用于'errs',在这种情况下结果应该包含错误数组上的 Chrome 和 Safari
  • 这里的结果应该是"errs": [ { "userAgent": "Safari" } ]
【解决方案2】:

你可以使用一些外部模块吗? 例如,可以使用 lodash 模块 https://lodash.com/docs/4.17.10#merge

(顺便说一句:npm https://www.npmjs.com/search?q=deep%20merge 中有很多类似的库)

【讨论】:

    【解决方案3】:

    var originData = {
      "userAgents": [
          "Chrome",
          "Safari"
      ],
      "tests": [
          {
              "name": "a",
              "errs": []
          },
          {
              "name": "b",
              "errs": [
                  {
                      "userAgent": "Chrome"
                  },
                  {
                      "userAgent": "Safari"
                  }
              ]
          }
      ]
    };
    
    var newData = {
      "userAgents": [
          "Chrome"
      ],
      "tests": [
          {
              "name": "a",
              "errs": []
          },
          {
              "name": "b",
              "errs": [
                {"userAgent": "Chrome"}
              ]
          }
      ]
    };
    
    originData.tests.forEach(originItem => {
      originItem.errs = originItem.errs.filter(e => (newData.userAgents.indexOf(e.userAgent) < 0 ));
    });
    
    newData.tests.forEach( newDataItem => {
      let originDataItem = originData.tests.filter(obj=>obj.name===newDataItem.name)
      newDataItem.errs.forEach( err => {
        originDataItem[0].errs.push( err )
      })
    })
    
    
    console.log(originData);

    【讨论】:

    • 实际上,如果newData 上的错误是[{"userAgent": "Chrome"}],则结果数组仍然是safari,应该是"errs": [ { "userAgent": "Chrome" }, { "userAgent": "Safari" } ]
    猜你喜欢
    • 2020-07-21
    • 2018-05-07
    • 1970-01-01
    • 2017-04-27
    • 2017-04-22
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多