【问题标题】:How to update JSON data如何更新 JSON 数据
【发布时间】:2019-01-29 22:49:50
【问题描述】:

我想得到更新两个 json 数据的结果,第二个 json 更新了第一个 json 中的现有数据并且它也有新数据,这些是我的结构:

var origin = {
  "allTest": [
    {
      "testName": "A",
      "platform": [{"name": "chrome", "area": ["1"]}]
    },
    {
      "testName": "B",
      "platform": [{"name": "Edge", "area": ["2"]}]
    }
  ]
};

var updated = {
  "allTest": [
    {
      "testName": "A",
      "platform": [{"name": "chrome", "area": ["1"]}]
    },
    {
      "testName": "B",
      "platform": [{"name": "Safari", "area": ["3"]}]
    },
    {
      "testName": "C",
      "platform": [{"name": "IE", "area": ["4"]}]
    }
  ]
}

var result = origin.allTest.concat(updated.allTest);
console.log(result);

结果:

  [ { testName: 'A', platform: [ [Object] ] },
  { testName: 'B', platform: [ [Object] ] },
  { testName: 'A', platform: [ [Object] ] },
  { testName: 'B', platform: [ [Object] ] },
  { testName: 'C', platform: [ [Object] ] } ]

但这不是当前的更新,我想像这样更新原始数据:

预期结果:

{
  "allTest": [
    {
      "testName": "A",
      "platform": [{"name": "chrome", "area": ["1"]}]
    },
    {
      "testName": "B",
      "platform": [{"name": "Edge", "area": ["2"]},{"name": "Safari", "area": ["3"]}]
    },
    {
      "testName": "C",
      "platform": [{"name": "IE", "area": ["4"]}]
    }
  ]
}

你能帮我解决它吗?我是编码新手,谢谢

【问题讨论】:

标签: javascript arrays json loops object


【解决方案1】:

使用JsonPatch。根据您使用的技术,您会找到不同的工具来实现这一点。一个 JsonPatch 文档基本上就是一个描述原始文档变化的 Json。

【讨论】:

  • 其实我想用 java script 或 lodash 解决
  • 有没有其他不使用外部库的方法。
【解决方案2】:

您可以像这样使用扩展运算符:

var result = { ...origin, ...updated };

【讨论】:

【解决方案3】:

您可以使用函数递归地遍历目标对象并适当地添加它。

根据我对您的结构的了解,如果测试名称相等,您需要特定的逻辑来处理连接平台。我在这里写了一个快速函数作为示例,但是这个函数不检查重复项。请原谅我的草率代码,我也是 javascript 新手。

var origin = {
  "allTest": [
    {
      "testName": "A",
      "platform": [{"name": "chrome", "area": ["1"]}]
    },
    {
      "testName": "B",
      "platform": [{"name": "Edge", "area": ["2"]}]
    }
  ]
};

var updated = {
  "allTest": [
    {
      "testName": "A",
      "platform": [{"name": "chrome", "area": ["1"]}]
    },
    {
      "testName": "B",
      "platform": [{"name": "Safari", "area": ["3"]}]
    },
    {
      "testName": "C",
      "platform": [{"name": "IE", "area": ["4"]}]
    }
  ]
}

function concatJson(source, target)
{
    var result = target;

     for (var i in source.allTest)
     {
         var found = false;
         for (var j in result.allTest)
         {
             //if the testname is the same we need to concat the platform
             if(!found && source.allTest[i].testName == result.allTest[j].testName)
             {
                result.allTest[i].platform = source.allTest[i].platform.concat(result.allTest[j].platform)
                found = true;
             }
        }
        if(!found)
        {
            //no match found so we'll add the tuple to the list
            result.allTest = result.allTest.concat(source.allTest[i]);
        }
    }
    return result;
}

var result = concatJson(updated, origin);
console.log(JSON.stringify(result, null, 4));

【讨论】:

    【解决方案4】:

    这是一个不使用库的解决方案,但它不是动态的,因此仅针对您的用例量身定制。

    我被屏蔽了,无法让它更优化,所以欢迎任何反馈:)

    const origin = {
      allTest: [
        {
          testName: 'A',
          platform: [{ name: 'chrome', area: ['1'] }],
        },
        {
          testName: 'B',
          platform: [{ name: 'Edge', area: ['2'] }],
        },
      ],
    }
    
    const updated = {
      allTest: [
        {
          testName: 'A',
          platform: [{ name: 'chrome', area: ['1'] }],
        },
        {
          testName: 'B',
          platform: [{ name: 'Safari', area: ['3'] }],
        },
        {
          testName: 'C',
          platform: [{ name: 'IE', area: ['4'] }],
        },
      ],
    }
    
    const findAndMergePlatforms = (array, item) =>
      array
        .filter(o => o.testName === item.testName)
        .map(o => ({ ...o, platform: [...o.platform, ...item.platform] }))
    
    const removeExisting = (array, item) =>
      array.filter(o => o.testName !== item.testName)
    
    const removeDuplicatePlatforms = platforms =>
      platforms.reduce(
        (acc, curr) =>
          acc.filter(({ name }) => name === curr.name).length > 0
            ? acc
            : [...acc, curr],
        []
      )
    
    const mergedAllTests =
      // Merge "allTest" objects from both arrays
      [...origin.allTest, ...updated.allTest]
    
        // Merge the "platform" properties
        .reduce((acc, curr) => {
          const found = findAndMergePlatforms(acc, curr)
          acc = removeExisting(acc, curr)
          return found.length !== 0 ? [...acc, ...found] : [...acc, curr]
        }, [])
    
        // Remove platform duplicates
        .map(({ testName, platform }) => ({
          testName,
          platform: removeDuplicatePlatforms(platform),
        }))
    
    const result = { allTest: mergedAllTests }
    
    const util = require('util')
    console.log(util.inspect(result, { showHidden: false, depth: null }))
    

    编辑: 添加了 cmets,并修复了结果以包含 allTest 对象。

    【讨论】:

      猜你喜欢
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2017-07-16
      • 2021-07-05
      相关资源
      最近更新 更多