0
\$\begingroup\$

Is there a better or simplified approach to create an array which contains one object per objectid with an array of contacts that matches globalLkupRemoveContactReviewer by userid and then send each array which contains one object to the database in the form of

[
  {
    objectid: '222',
    contacts: [
      { isdelete: '1', contactid: '1', associationid: '1968398' },
      { isdelete: '1', contactid: '2', associationid: '1968399' },
    ],
  },
];
I get a dynamic string in the form of values separated by , and each value is separated by * in the format of objectid, userid, associationid

const globalLkupRemoveContactReviewer = [
  { objectid: 555, userid: '1', associationid: '1948874' },
  { objectid: 555, userid: '2', associationid: '1950833' },
];
//My Code: 
var myStr = '111*1*1968397,222*1*1968398,222*2*1968399,333*2*1968401,333*4*1968402,333*1*19684034';
Object.values(
  myStr
    .split(',')
    .map((item) => item.split('*'))
    .map(([objectid, userid, associationid]) => ({
      objectid,
      userid,
      associationid,
    }))
    .filter(
      (item1) =>
        !!globalLkupRemoveContactReviewer.find(
          (item2) => item2.userid === item1.userid
        )
    )
    .reduce((acc, { objectid, userid, associationid }) => {
      (acc[objectid] ??= { objectid, contacts: [] }).contacts.push({
        isdelete: '1',
        contactid: userid,
        associationid,
      });
      return acc;
    }, {})
).forEach((item) => {
  console.log([item]);
});

// Need result in this format to send to the database
// [ { "objectid": "111", "contacts": [ { "isdelete": "1", "contactid": "1", "associationid": "1968397" } ] } ]
// [ { "objectid": "222", "contacts": [ { "isdelete": "1", "contactid": "1", "associationid": "1968398" }, { "isdelete": "1", "contactid": "2", "associationid": "1968399" } ] } ]
// [ { "objectid": "333", "contacts": [ { "isdelete": "1", "contactid": "2", "associationid": "1968401" }, { "isdelete": "1", "contactid": "1", "associationid": "19684034" } ] } ]

\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

If I understand everything correctly, then this can be done easier. The code can be formatted in different ways. But the main thing is that there is less action. So:

  • we split the data into parts
  • then through reduce we form a common array of objects
  • parse data for object (including objectid)
  • check globalLkupRemoveContactReviewer if we should add something
  • to save space, we form a child object once
  • if we have an object with this objectid - update it otherwise create it

const globalLkupRemoveContactReviewer = [
  { objectid: 555, userid: '1', associationid: '1948874' },
  { objectid: 555, userid: '2', associationid: '1950833' },
];

const myStr = '111*1*1968397,222*1*1968398,222*2*1968399,333*2*1968401,333*4*1968402,333*1*19684034';
const data = myStr.split(',')
  .reduce((acc, e) => {
    const [objectid, contactid, associationid] = e.split('*')
    if (!globalLkupRemoveContactReviewer.find((item2) => 
      item2.userid === contactid)) return acc   // skip 

    const parent = acc.find(e => e.objectid === objectid)
    const child = { isdelete: "1", contactid, associationid }
    if (parent) {
      parent.contacts.push(child)     // append contact
    } else {
      acc.push({objectid,contacts: [child]}) // new object
    }
    return acc
  }, [])
console.log(JSON.stringify(data, null, 2))

As a result, we do not have unnecessary actions and operations.

UPDATE

Another great example of how to improve performance with reduce. The morbusg's answer has a use of Set, but you can create it in different ways. I suggest creating it in reduce - we will have one loop. In the case of new Set(x.map(...)) we have a map loop and an inner loop in the Set constructor.

const globalLkupRemoveContactReviewer = [
  { objectid: 555, userid: '1', associationid: '1948874' },
  { objectid: 555, userid: '2', associationid: '1950833' },
];
console.time('1')
for (let i=0; i<100; i++) 
  new Set(globalLkupRemoveContactReviewer.map(({userid}) => userid))
console.timeEnd('1')
console.time('2')
for (let i=0; i<100; i++) 
  globalLkupRemoveContactReviewer.reduce((acc, {userid}) => acc.has(userid) ? acc : acc.add(userid), new Set)
console.timeEnd('2')

The final version might look like this:

const globalLkupRemoveContactReviewer = [
  { objectid: 555, userid: '1', associationid: '1948874' },
  { objectid: 555, userid: '2', associationid: '1950833' },
];

const globalRemoveContactId = globalLkupRemoveContactReviewer
  .reduce((acc, {userid}) => acc.has(userid) ? acc : acc.add(userid), new Set)

const myStr = '111*1*1968397,222*1*1968398,222*2*1968399,333*2*1968401,333*4*1968402,333*1*19684034';

const data = myStr.split(',')
  .reduce((acc, e) => {
    const [objectid, contactid, associationid] = e.split('*')
    if (!globalRemoveContactId.has(contactid)) return acc   // skip 

    const parent = acc.find(e => e.objectid === objectid)
    const child = { isdelete: "1", contactid, associationid }
    if (parent) {
      parent.contacts.push(child)     // append contact
    } else {
      acc.push({objectid,contacts: [child]}) // new object
    }
    return acc
  }, [])
console.log(JSON.stringify(data, null, 2))

\$\endgroup\$
3
  • \$\begingroup\$ Hey I get item1 is not defined. \$\endgroup\$
    – Karim Ali
    Feb 28, 2023 at 19:03
  • \$\begingroup\$ @KarimAli I've updated the answer with some more explanatory details. \$\endgroup\$ Mar 2, 2023 at 23:02
  • \$\begingroup\$ Txs. Really Appreciated. \$\endgroup\$
    – Karim Ali
    Mar 3, 2023 at 14:47
1
\$\begingroup\$

The most expensive part is likely the Array.prototype.find inside the iteration, which can be remedied with a constant time lookup data structure such as a Set or even just a plain object keyed by userid:

const uniqUsers = new Set(globalLkupRemoveContactReviewer.map(({userid}) => userid))

and when filtering:

.filter (({userid}) => !uniqUsers.has(userid))

Please try to avoid such lengthy variables names as globalLkupRemoveContactReviewer.

\$\endgroup\$
1
  • \$\begingroup\$ Hey, do you mind providing your version? \$\endgroup\$
    – Karim Ali
    Mar 1, 2023 at 19:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.