【问题标题】:How to combine 2 Json objects into a single Json object using NodeJS?如何使用 NodeJS 将 2 个 Json 对象组合成一个 Json 对象?
【发布时间】:2020-04-27 16:10:39
【问题描述】:

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

【问题讨论】:

    标签: javascript arrays node.js performance mapreduce


    【解决方案1】:

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

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

    【讨论】:

    • 实际上在我的最终要求中,我有 3 个响应对象而不是 2 个。我想组合 res1res2res3。您能否相应地更新您的答案?我已经更新了我的问题。
    • @meallhour 只需使用第二个 [...res1, ...res2, ...res3] 就可以了
    • 第一个也可以扩展,只需要更新返回值{... inp, ...res2[index], ...res3[index] }
    【解决方案2】:

    基本上,您可以搜索具有共享属性的另一个数组:“主机名”并使用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 在 cmets 中提到的,有 3 个要合并的结果,所以我为任意数量的结果制定了一个通用方法。

    【讨论】:

    • 实际上在我的最终要求中,我有 3 个响应对象而不是 2 个。我想组合 res1res2res3。您能否相应地更新您的答案?我已经更新了我的问题。
    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    相关资源
    最近更新 更多