【问题标题】:Merge 2 arrays and created a new one [closed]合并 2 个数组并创建一个新数组 [关闭]
【发布时间】:2021-12-29 13:15:22
【问题描述】:

我有 2 个数组这个

let array1 = [
    {
        designation: "SSE",
        emailId: "abc@gmail.com",
        employeeId: 1997,
        firstName: "user2",
    },
    {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 19,
        firstName: "user1",
    },
    {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 191,
        firstName: "user1",
    },
];

let array2 = [
    {
        designation: "SSE",
        emailId: "abc@gmail.com",
        employeeId: 199,
        firstName: "user2",
    },
    {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 19,
        firstName: "user1",
    },
    {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 191,
        firstName: "user1",
    },
    {
        designation: "TESTER",
        emailId: "ab@gmail.com",
        employeeId: 1221,
        firstName: "user1",
    },
];

看,我在两个数组中都有一些共同的记录,而 array2 中缺少一个。如果employeeId 不匹配,我想将它们合并为一个。像这样。

let array3 = [
   {employeeId: 1997, isActive: false}, 
   {employeeId: 199, isActive: true}, 
   {employeeId: 19, isActive: true}, 
   {employeeId: 191, isActive: true},
   {employeeId: 1221, isActive: false}
]

array3[3].isActive 为 false,因为它在两个数组中都不匹配。

【问题讨论】:

  • 你能解释一下为什么employeeId: 199是真的而employeeId: 1221是假的吗?
  • 这是因为它们在两个数组中都不匹配。
  • @Gajen 1997array1 但不在array2,为什么是true
  • @Gajen employeeId: 199 在第一个数组中也不匹配,那么为什么它有isActive: true
  • 预期的结果仍然是错误的。请通过比较逻辑来纠正它。根据您的逻辑,只有 19199 为真,因为它们只是 copmmon 元素。

标签: javascript html reactjs


【解决方案1】:
  1. array1获取一个employeeId数组
  2. array2 获取一组employeeId
  3. 创建一个包含所有 (unique) emplyeeId 的数组
  4. Create an array with the ID's that are not matching
  5. map() 将所有 id (array_0_ids) 转换为:
    1. 创建一个对象
    2. isActive 设置为!non_matching.includes(emplyeeId) 的结果

let array1 = [{designation: "SSE", emailId: "abc@gmail.com", employeeId: 199, firstName: "user2", }, {designation: "DEVELOPER", emailId: "ab@gmail.com", employeeId: 19, firstName: "user1", }, {designation: "DEVELOPER", emailId: "ab@gmail.com", employeeId: 191, firstName: "user1", }, ];
let array2 = [{designation: "SSE", emailId: "abc@gmail.com", employeeId: 199, firstName: "user2", }, {designation: "DEVELOPER", emailId: "ab@gmail.com", employeeId: 19, firstName: "user1", }, {designation: "DEVELOPER", emailId: "ab@gmail.com", employeeId: 191, firstName: "user1", }, {designation: "TESTER", emailId: "ab@gmail.com", employeeId: 1221, firstName: "user1", }, ];

let array_1_ids = array1.map(i => i.employeeId);
let array_2_ids = array2.map(i => i.employeeId);
let array_0_ids = [ ...array_1_ids, ...array_2_ids ].filter((v, i, s) => s.indexOf(v) === i);

let non_matching = array_2_ids.filter(id => !array_1_ids.includes(id));

let result = array_0_ids.map(emplyeeId => {
  return {
    emplyeeId,
    isActive: !non_matching.includes(emplyeeId)
  };
});

console.log(result);
[
  {"emplyeeId": 199, "isActive": true },
  {"emplyeeId": 19, "isActive": true}, 
  {"emplyeeId": 191, "isActive": true},
  {"emplyeeId": 1221, "isActive": false} 
]

【讨论】:

  • 请验证提问者的逻辑是否正确。
【解决方案2】:
let result = [];

const employeeIdArray2 = array2.map(e => e.employeeId);
const employeeIdArray1 = array1.map(e => e.employeeId);

const missingEmployeeIdArray = employeeIdArray2.length > employeeIdArray1.length ? employeeIdArray1 : employeeIdArray2;

result = array2.map(e => {
  if (missingEmployeeIdArray.includes(e.employeeId)) {
    return {
      ...e,
      isActive: true
    }
  } else {
    return {
      ...e,
      isActive: false
    }
  }
})

【讨论】:

  • 如果我在 array1 中有不同的数据,这种方法将不起作用。我认为我们需要在他们两个上循环
  • @Gajen 你想要2路合并?
  • @Gajen 我更新了
【解决方案3】:

您可以使用来自 lodash 的 uniqBy method

const mergedArray = uniqBy([...array1, ...array2], "employeeId");

查看stackblitz 上的实时示例。

【讨论】:

    【解决方案4】:
    mergeArr = ():any[] => {
    return this.array1.map(
      e => {
        if(this.array2.map(x=>x.employeeId).includes(e.employeeId)){
          return {employeeId:e.employeeId, isActive:true};
        }else{
          return {employeeId:e.employeeId, isActive:false};
        }
      }
    )
    

    }

    这可能行得通..

    更新了一个..

    mergeArr = ():any[] => {
    let addedEmployees = new Set<number>();
    let arr3 =  this.array1.map(
      e => {
        addedEmployees.add(e.employeeId);
        if(this.array2.map(x=>x.employeeId).includes(e.employeeId)){
          return {employeeId:e.employeeId, isActive:true};
        }else{
          return {employeeId:e.employeeId, isActive:false};
        }
      }
    )
    
    this.array2.forEach(e => {
      if(!addedEmployees.has(e.employeeId)){
        arr3.push({employeeId:e.employeeId, isActive:false});
      }
    })
    
    return arr3;
    

    }

    【讨论】:

    • 如果我在两个数组中有不同的数组项,这将不起作用。
    【解决方案5】:
    1. 创建一个对象,其中键是employeeId,值是出现次数
    2. 通过迭代对象条目创建最终数组,当出现次数为 2 时将 isActive 设置为 true。

    const array1 = [
      {
        designation: "SSE",
        emailId: "abc@gmail.com",
        employeeId: 199,
        firstName: "user2",
      },
      {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 19,
        firstName: "user1",
      },
      {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 191,
        firstName: "user1",
      },
    ];
    
    const array2 = [
      {
        designation: "SSE",
        emailId: "abc@gmail.com",
        employeeId: 199,
        firstName: "user2",
      },
      {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 19,
        firstName: "user1",
      },
      {
        designation: "DEVELOPER",
        emailId: "ab@gmail.com",
        employeeId: 191,
        firstName: "user1",
      },
      {
        designation: "TESTER",
        emailId: "ab@gmail.com",
        employeeId: 1221,
        firstName: "user1",
      },
    ];
    
    const reducer = (acc, e) => ({
      ...acc,
      [e.employeeId]: (acc[e.employeeId] + 1) || 1,
    }); 
    
    const arr3 = Object.entries([...array1, ...array2].reduce(reducer, {}))
      .map(([employeeId, count]) => ({ employeeId, isActive: count == 2 }));
      
    console.log(arr3);

    【讨论】:

    • 请验证提问者的逻辑是否正确。
    【解决方案6】:

    将您的问题解释为“如果两个数组中都存在 employeeId,则 true,否则 false”。

    这可以通过构建地图来解决。您甚至可以在之后继续使用地图,而不是在最后转换回 Array

    // Set up the initial Map using `array1`'s values, assume everything is different
    const employeeStatus = new Map(
      array1.map(({ employeeId }) => [employeeId, false]),
    );
    
    // if `array2` has the same employeeId then set `true`, otherwise add a false entry
    array2.forEach(({ employeeId }) => {
      // for something more complex, you could also do some other logic here
      const seen = employeeStatus.has(employeeId);
      employeeStatus.set(employeeId, seen);
    });
    
    
    // convert the Map to the output data structure
    const result = [...employeeStatus].map(([employeeId, isActive]) => ({
      employeeId,
      isActive,
    }));
    

    这给了

    [
      { employeeId: 1997, isActive: false },
      { employeeId: 19, isActive: true },
      { employeeId: 191, isActive: true },
      { employeeId: 199, isActive: false },
      { employeeId: 1221, isActive: false },
    ]
    

    【讨论】:

    • 请投票结束这个问题。提问者没有提供任何尝试,预期的输出和逻辑不匹配。这需要回答吗?
    • @Nitheesh 偷偷摸摸地在收盘前得到这个答案,已经投票了
    • 您可以避免回答此类问题以保持社区清洁。提问者没有提供任何有效的尝试,甚至预期的输出也不正确。这就像我们必须处理询问者没有尝试过任何事情的要求。
    猜你喜欢
    • 2012-09-11
    • 1970-01-01
    • 2018-08-01
    • 2013-06-19
    • 2017-11-14
    • 1970-01-01
    • 2021-02-24
    • 2020-06-22
    • 2021-06-23
    相关资源
    最近更新 更多