如何使用 NodeJS 将 2 Json 个对象组合成一个 Json 对象?

How to combine 2 Json objects into a single Json object using NodeJS?

我有 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 Res2Res3

基本上你可以用共享 属性 搜索另一个数组:"Hostname" 并使用 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 在评论中提到的那样,有 3 个结果要合并,所以我为任意数量的结果制定了一个通用方法。

您可以只映射一个数组并使用索引从另一个数组中获取相应的值并合并值

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)

P.S:- 这考虑了数组按相同顺序排序,并且始终在其他数组中存在相应的值。 (考虑到您给定的示例数据)。如果不是这种情况,那么我们只需要根据一些 属性 和合并从其他数组中找到相应的值。

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()])