-1

I have 2 arrays this

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",
    },
];

See, I have some common records in both arrays and one is missing in array2. I want to merge them into one if employeeId doesn't match. Like this.

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 is false because it doesn't match in both arrays.

Gajen
  • 456
  • 1
  • 5
  • 17

6 Answers6

1
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
    }
  }
})
1
  1. Get an array of employeeId from array1
  2. Get an array of employeeId from array2
  3. Create an array with all the (unique) emplyeeId's
  4. Create an array with the ID's that are not matching
  5. map() over all the ids (array_0_ids) to:
    1. Create an object
    2. Set isActive to the result of !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} 
]
0stone0
  • 34,288
  • 4
  • 39
  • 64
0

You can use the uniqBy method from lodash.

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

Check out the live example on stackblitz.

szaman
  • 2,159
  • 1
  • 14
  • 30
0
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};
    }
  }
)

}

This might work..

Updated one..

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;

}

Mahadev K
  • 330
  • 2
  • 9
0
  1. Create an object where the key will be the employeeId and the value will be the number of occurrences
  2. Create the final array by iterating over the object entries, set isActive to true when the number of occurrences is 2.

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);
Olivier Boissé
  • 15,834
  • 6
  • 38
  • 56
0

Interpreting your question as "If an employeeId is present in both arrays then true, otherwise false".

This is solvable by building a Map. You may even be able to continue working with the map after, rather than converting back into an Array at the end

// 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,
}));

Which gives

[
  { employeeId: 1997, isActive: false },
  { employeeId: 19, isActive: true },
  { employeeId: 191, isActive: true },
  { employeeId: 199, isActive: false },
  { employeeId: 1221, isActive: false },
]
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • Please vote to close the question. The asker doesnot have provided any attempts, the expected output and the logic are not matching. Does this needs to be answered? – Nitheesh Dec 29 '21 at 14:13
  • @Nitheesh being sneaky and getting this answer in before the close, have voted – Paul S. Dec 29 '21 at 14:14
  • You could avoid answering these kind of questions to keep the community clean. The asker have not provided any valid attempts and even the expected output is not correct. This is like we have to work on a requirement where the asker has not attempted anything from their side. – Nitheesh Dec 30 '21 at 04:30