【问题标题】:Merge two array of objects based on a key value compare基于键值比较合并两个对象数组
【发布时间】:2021-09-19 14:20:59
【问题描述】:

我正在尝试合并两个对象,它们都具有相同的相似键,但值不同。我希望他们保留不同的键,但将它们放在匹配的键值中

这是我的第一个 obj,

const obj1 = [
      {
        "p_id": 1,
        "name": "Peter",
        "status" : "Active"
      },
      {
        "p_id": 2,
        "name": "Kane",
        "status" : "Active"
      },
      {
        "p_id": 3,
        "name": "William",
        "status" : "Inactive"
      }
]


}

我的第二个对象,

const obj2 = [
  { p_id: 1, type: 'home', no: '+01 234 5678' },
  { p_id: 1, type: 'work', no: '+09 111 2223' },
  { p_id: 2, type: 'home', no: '+12 345 6789' },
]

其实我是这样做的,

 obj1.forEach((item) => {
            Object.assign(item, {
                phone: obj2.find(
                    (o) => o.p_id === item.p_id
                )
            });
        });
// console.log(obj1) would be

[
      {
        "p_id": 1,
        "name": "Peter",
        "status" : "Active",
        "phone" : {type: 'home', no: '+01 234 5678'}       
      },
      {
        "p_id": 2,
        "name": "Kane"
        "status" : "Active",
        "phone" : {type: 'home', no: '+12 345 6789'} 
      },
      {
        "p_id": 3,
        "name": "William"
        "status" : "Inactive"
        "phone" : undefined
      }

]

但这不是我想要的。我想成为最终结果我需要的是这些数组之间的比较——最终结果应该是这样的:

const result = [
      {
        "p_id": 1,
        "name": "Peter",
        "status" : "Active",
        "phone" : [
           {type: 'home', no: '+01 234 5678'},
           {type: 'work', no: '+09 111 2223'}        
        ]
      },
      {
        "p_id": 2,
        "name": "Kane"
        "status" : "Active",
        "phone" : [
           {type: 'home', no: '+12 345 6789'}      
        ]
      },
      {
        "p_id": 3,
        "name": "William"
        "status" : "Inactive"
        "phone" : []
      }

]

非常感谢您的帮助, 谢谢!

【问题讨论】:

  • 这不是代码编写服务。向我们展示您所做的实际尝试,并正确解释问题到底出在哪里。 How to Ask, minimal reproducible example
  • @CBroe 当然我明白了,实际上我确实尝试了一些不同的方法..但最后我能够找到类似这个更新问题的东西。 (我更新了问题)。谢谢

标签: javascript node.js arrays object


【解决方案1】:

这是最好的方法


// intersect can be simulated via
const intersection = new Set([...mySet1].filter(x => mySet2.has(x)))

// difference can be simulated via
const difference = new Set([...mySet1].filter(x => !mySet2.has(x)))


【讨论】:

    【解决方案2】:

    而不是Array.find 尝试Array.filter 方法。 find 只会返回第一个元素,filter 会返回所有满足条件的元素:

    Object.assign(item, {
        phone: obj2.filter(
           (o) => o.p_id === item.p_id
        )
     });
    

    【讨论】:

    • 谢谢,实际上这个小代码 sn-p 与我的解决方案相符,但有一件事 @Shuvo 最终结果电话属性也具有 p_id 属性。有什么可以删除这个 p_id 表单 result.phone 对象数组会很好
    • 你可以链接map方法来选择你需要的属性:phone: obj2.filter((o) => o.p_id === item.p_id ).map(item => ({type: item.type, no: item.no}))
    【解决方案3】:

    你可以这样做:

    const users = [
      {
        p_id: 1,
        name: "Peter",
        status: "Active",
      },
      {
        p_id: 2,
        name: "Kane",
        status: "Active",
      },
      {
        p_id: 3,
        name: "William",
        status: "Inactive",
      },
    ];
    
    const phoneNumbers = [
      { p_id: 1, type: "home", no: "+01 234 5678" },
      { p_id: 1, type: "work", no: "+09 111 2223" },
      { p_id: 2, type: "home", no: "+12 345 6789" },
    ];
    
    const mergeArrays = (arr1, arr2) => {
      return arr1.map((obj) => {
        const numbers = arr2.filter((nums) => nums["p_id"] === obj["p_id"]);
        if (!numbers.length) {
          obj.phone = numbers;
          return obj;
        }
        obj.phone = numbers.map((num) => ({ type: num.type, no: num.no }));
        return obj;
      });
    };
    
    const result = mergeArrays(users, phoneNumbers);
    console.log(result);

    说明:

    使用filter 方法在phoneNumbers 数组中查找所有具有相同id 的对象。然后在匹配的电话号码上循环使用map方法,并返回一个不带id的电话号码对象。

    【讨论】:

      猜你喜欢
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-08
      • 2016-05-07
      • 1970-01-01
      相关资源
      最近更新 更多