Как обновить данные JSON - PullRequest
       4

Как обновить данные JSON

0 голосов
/ 30 января 2019

Я хочу получить результат обновления двух данных 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);

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"]}]
    }
  ]
}

не могли бы вы помочь мнереши это.я новичок в кодировании, спасибо

Ответы [ 4 ]

0 голосов
/ 30 января 2019

Вот решение, которое не использует библиотеки, но оно не динамическое, поэтому оно адаптировано только для вашего случая использования.

Я заблокирован и не смог сделать его более оптимальным, поэтому любая обратная связьможно только приветствовать:)

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 }))

Редактировать: Добавлены комментарии и исправлен результат, включающий allTest объект.

0 голосов
/ 30 января 2019

Вы можете использовать оператор распространения следующим образом:

var result = { ...origin, ...updated };
0 голосов
/ 30 января 2019

Вы можете использовать функцию для рекурсивной итерации целевого объекта и добавления его соответствующим образом.

Исходя из того, что я понимаю о вашей структуре, вам нужна особая логика для объединения платформ, если имя теста равно.Я написал быструю функцию в качестве примера, но этот не проверяет дубликаты.Простите за небрежный код, я также новичок в 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));
0 голосов
/ 30 января 2019

Используйте JsonPatch .В зависимости от используемой вами технологии, вы найдете различные инструменты для ее реализации.Документ JsonPatch - это, по сути, Json, который описывает изменения в исходном документе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...