简体   繁体   English

Javascript:在同一键上合并 JSON 对象的列表并删除未合并的对象

[英]Javascript: Merge List of JSON Objects on Same Key and Drop Un-merged Objects

I've looked through every "Merge JSON Objects on Same Key" question in SO, but to no avail.我已经查看了 SO 中的每个“在同一键上合并 JSON 对象”问题,但无济于事。

I have two arrays of different-length JSON objects, like so, and I need to merge each JSON object that has a shared key (in this case, realName ) and dump what is not appearing in both: I have two arrays of different-length JSON objects, like so, and I need to merge each JSON object that has a shared key (in this case, realName ) and dump what is not appearing in both:

  let arrObjA = [{
    "index": 114,
    "realName": 'kevin',
    "bucket": 'boss',
    "react_name": 'BossKevin'
  },
  {
    "index": 115,
    "realName": 'angela',
    "bucket": 'boss',
    "react_name": 'BossAngela'
  },
  {
    "index": 116,
    "realName": 'james',
    "bucket": 'janitor',
    "react_name": 'JanitorJames'
  },
  {
    "index": 117,
    "realName": 'arthur',
    "bucket": 'employee',
    "react_name": 'EmployeeArthur'
  }
]

And

let arrObjB = [{
        "boxName": "building",
        "realName": "angela",
        "boxValue": "2"
      },
      {
        "boxName": "building",
        "realName": "james",
        "boxValue": "false"
      },
      {
        "boxName": "building",
        "realName": "arthur",
        "boxValue": "0"
      },
      ]

The result should be:结果应该是:

let result = [{
    "index": 115,
    "realName": 'angela',
    "bucket": 'boss',
    "react_name": 'BossAngela',
    "boxName": "building",
    "boxValue": "2"
  },
  {
    "index": 116,
    "realName": 'james',
    "bucket": 'janitor',
    "react_name": 'JanitorJames',
    "boxName": "building",
    "boxValue": "false"
  },
  {
    "index": 117,
    "realName": 'arthur',
    "bucket": 'employee',
    "react_name": 'EmployeeArthur',
    "boxName": "building",
    "boxValue": "0"
  }
]

So the new JSON objects in the new array ( result ) are merged JSON object where the key realName is shared between the original JSON objects (eg, arrObjA["realName"] === arrObjB["realName"] ). So the new JSON objects in the new array ( result ) are merged JSON object where the key realName is shared between the original JSON objects (eg, arrObjA["realName"] === arrObjB["realName"] ). And the one JSON object with the realName "kevin" from arrObjA is not in the new array since it that key/value does not appear in a JSON object in both arrays. And the one JSON object with the realName "kevin" from arrObjA is not in the new array since it that key/value does not appear in a JSON object in both arrays.

I have tried the following from another SO answer, which has brought me closest to the result I need (out of all the other few dozen answers that I've tried), but I only get a single key/value because I don't know how to expand the objects.我从另一个 SO 答案中尝试了以下内容,这使我最接近我需要的结果(在我尝试过的所有其他几十个答案中),但我只得到一个键/值,因为我没有知道如何扩展对象。

const mappingEngine = (arrA, arrB) => {
  const resultsKeys = ["realName", "bucket"];

  const result = arrA
    .filter(function (o1) {
      return arrB.some(function (o2) {
        return o1.realName === o2.realName; // assumes unique id
      });
    })
    .map(function (o) {
      console.log(o)
      return resultsKeys.reduce(function (newo, name) {
        newo[name] = o[name];
        return newo;
      }, {});
    });
  return result;
};

Thank you for any help.感谢您的任何帮助。

You can use es6 spread ( ... ) operator to marge two objects.您可以使用 es6 spread ( ... ) 运算符来对齐两个对象。

 let arrObjA = [{ "index": 114, "realName": 'kevin', "bucket": 'boss', "react_name": 'BossKevin' }, { "index": 115, "realName": 'angela', "bucket": 'boss', "react_name": 'BossAngela' }, { "index": 116, "realName": 'james', "bucket": 'janitor', "react_name": 'JanitorJames' }, { "index": 117, "realName": 'arthur', "bucket": 'employee', "react_name": 'EmployeeArthur' }] let arrObjB = [{ "boxName": "building", "realName": "angela", "boxValue": "2" }, { "boxName": "building", "realName": "james", "boxValue": "false" }, { "boxName": "building", "realName": "arthur", "boxValue": "0" },] let result = arrObjB.map(item => ({...arrObjA.find(({ realName }) => item.realName == realName), ...item, })); console.log(result)

I have a different approach for your problem.对于您的问题,我有不同的方法。 I don't use reduce.我不使用减少。 I map the first array and inside the mapping filter the first element from the second array that match with the actual element mapped.我 map 第一个数组和映射内部过滤了第二个数组中与映射的实际元素匹配的第一个元素。 Here how I did it with code:这是我如何用代码做到的:

 let arrObjA = [{ "index": 114, "realName": 'kevin', "bucket": 'boss', "react_name": 'BossKevin' }, { "index": 115, "realName": 'angela', "bucket": 'boss', "react_name": 'BossAngela' }, { "index": 116, "realName": 'james', "bucket": 'janitor', "react_name": 'JanitorJames' }, { "index": 117, "realName": 'arthur', "bucket": 'employee', "react_name": 'EmployeeArthur' } ]; let arrObjB = [{ "boxName": "building", "realName": "angela", "boxValue": "2" }, { "boxName": "building", "realName": "james", "boxValue": "false" }, { "boxName": "building", "realName": "arthur", "boxValue": "0" }, ]; const mappingEngine = (arrA, arrB) => { const a_key = "realName"; const b_key = "realName"; const result = arrA.map(function(o) { let b = arrB.filter(n_b => o[a_key] == n_b[b_key]); //Take the first element that is compatible if (b == null) { return { o }; } else { let c = b[0]; return {...o, ...c }; } }); console.log(result); return result; }; mappingEngine(arrObjA,arrObjB);

Please use filter to remove the keys that are on arrA but not on arrB.请使用过滤器删除 arrA 上而不是 arrB 上的密钥。 I just do a left join from arrA to arrB.我只是从 arrA 到 arrB 进行左连接。 It is like: SELECT * FROM arrA LEFT JOIN arrB;就像: SELECT * FROM arrA LEFT JOIN arrB;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM