Как объединить 2 Json объектов в один Json объект, используя NodeJS? - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть 3 JSON объектов, как определено ниже:

 const totalData = [{ Hostname: "abc123", name: "CName-A", Status: "PASS", Heading: "Not Applicable" },
            { Hostname: "abc123", name: "CName-B", Status: "FAIL", Heading: "Not Applicable" },
            { Hostname: "abc235", name: "CName-C", Status: "FAIL", Heading: "Not Applicable" },
            { Hostname: "abc235", name: "CName-D", Status: "FAIL", Heading: "Not Applicable" }];

const otherTotalData = [{ Hostname: "abc123", name: "QName-A", Status: "PASS", Heading: "HeadingQA" },
            { Hostname: "abc123", name: "QName-B", Status: "FAIL", Heading: "HeadingQB" },
            { Hostname: "abc235", name: "QName-C", Status: "FAIL", Heading: "Not Applicable" },
            { Hostname: "abc235", name: "QName-D", Status: "FAIL", Heading: "Not Applicable" }];

const newTotalData = [{ Hostname: "abc123", name: "TName-A", Status: "PASS", Heading: "HeadingTA" },
            { Hostname: "abc123", name: "TName-B", Status: "FAIL", Heading: "HeadingTB" },
            { Hostname: "abc235", name: "TName-C", Status: "FAIL", Heading: "Not Applicable" },
            { Hostname: "abc235", name: "TName-D", Status: "FAIL", Heading: "Not Applicable" }];                

У меня есть функция, которая использует array reduce метод:

function createArray(totalData) {
const keyValues = ["Status", "Heading"],
    result = Object.values(totalData.reduce((res, { Hostname, name, ...o }) => {
        res[Hostname] = res[Hostname] || { Hostname };
        keyValues.forEach(k => res[Hostname][name + k] = o[k]);
        return res;
    }, {}));
}

Теперь я вызываю два функции:

const Res1 = createArray(totalData);

const Res2 = createArray(otherTotalData);

const Res3 = createArray(newTotalData);

Здесь Res1 имеет выход:

[
    {
    "Hostname": "abc123",
    "CName-AStatus": "PASS",
    "CName-BStatus": "FAIL"
    },
    {
    "Hostname": "abc235",
    "CName-CStatus": "FAIL",
    "CName-DStatus": "FAIL"
    }
]

И, Res2 имеет выход:

[
    {
    "Hostname": "abc123",
    "QName-AStatus": "PASS",
    "QName-BStatus": "FAIL"
    },
    {
    "Hostname": "abc235",
    "QName-CStatus": "FAIL",
    "QName-DStatus": "FAIL"
    }
]

И, Res3 имеет выход:

[
    {
    "Hostname": "abc123",
    "TName-AStatus": "PASS",
    "TName-BStatus": "FAIL"
    },
    {
    "Hostname": "abc235",
    "TName-CStatus": "FAIL",
    "TName-DStatus": "FAIL"
    }
]

Я хочу объединить Res1, Res2 и Res3 так, чтобы конечный объект Json выглядел следующим образом:

[
    {
    "Hostname": "abc123",
    "CName-AStatus": "PASS",
    "CName-BStatus": "FAIL",
    "QName-AStatus": "PASS",
    "QName-BStatus": "FAIL",
    "TName-AStatus": "PASS",
    "TName-BStatus": "FAIL"
    },
    {
    "Hostname": "abc235",
    "CName-CStatus": "FAIL",
    "CName-DStatus": "FAIL",
    "QName-CStatus": "FAIL",
    "QName-DStatus": "FAIL",
    "TName-CStatus": "FAIL",
    "TName-DStatus": "FAIL"
    }
]

Как я могу объединить Res1 Res2 и Res3

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

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

let res1 = [{"Hostname": "abc123","CName-AStatus": "PASS","CName-BStatus": "FAIL"},{"Hostname": "abc235","CName-CStatus": "FAIL","CName-DStatus": "FAIL"}]
let res2 = [{"Hostname": "abc123","QName-AStatus": "PASS","QName-BStatus": "FAIL"},{"Hostname": "abc235","QName-CStatus": "FAIL","QName-DStatus": "FAIL"}]

let final = res1.map((inp, index) => {
  return { ...inp,
    ...res2[index]
  }
})

console.log(final)

PS: - Это считает, что массивы отсортированы в том же порядке, и всегда соответствующее значение присутствует в другом массиве. (учитывая данные вашего примера). Если это не так, то нам просто нужно найти соответствующее значение из другого массива на основе некоторого свойства и слияния.

let res1 = [{"Hostname": "abc123","CName-AStatus": "PASS","CName-BStatus": "FAIL"},{"Hostname": "abc235","CName-CStatus": "FAIL","CName-DStatus": "FAIL"}]
let res2 = [{"Hostname": "abc235","QName-CStatus": "FAIL","QName-DStatus": "FAIL"},{"Hostname": "abc123","QName-AStatus": "PASS","QName-BStatus": "FAIL"}]


let final = [...res1,...res2].reduce((op,inp)=>{
  let key = inp.Hostname
  if(op.has(key)){
    op.set(key, {...op.get(key), ...inp} )
  } else{
    op.set(key, inp)
  }
  return op
}, new Map())

console.log([...final.values()])
1 голос
/ 27 апреля 2020

По сути, вы можете искать другой массив с общим свойством: "Имя хоста" и использовать Object.assign для объединения двух объектов.

const res1 = [{
    "Hostname": "abc123",
    "CName-AStatus": "PASS",
    "CName-BStatus": "FAIL"
  },
  {
    "Hostname": "abc235",
    "CName-CStatus": "FAIL",
    "CName-DStatus": "FAIL"
  }
];

const res2 = [{
    "Hostname": "abc123",
    "QName-AStatus": "PASS",
    "QName-BStatus": "FAIL"
  },
  {
    "Hostname": "abc235",
    "QName-CStatus": "FAIL",
    "QName-DStatus": "FAIL"
  }
];

const res3 = [{
    "Hostname": "abc123",
    "TName-AStatus": "PASS",
    "TName-BStatus": "FAIL"
  },
  {
    "Hostname": "abc235",
    "TName-CStatus": "FAIL",
    "TName-DStatus": "FAIL"
  }
];

function mergeAll(key, ...args) {
  const arr = Array.from(args);
  const first = arr[0];
  const rest = arr.slice(1);

  return first.map(r => Object.assign({}, r, ...rest.map(q => q.find(t => t[key] === r[key]))));
}

const result = mergeAll('Hostname', res1, res2, res3);
console.log(result);

Редактировать: Как упоминалось в комментариях Op, есть три результата для слияния, поэтому я сделал обобщенный метод для любого количества результатов.

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