3

I have an object that I want to remove elements from one of its' properties that is an array of objects based on a matching property of the outer object.

This uses npm deep-diff to compare the two objects.

My problem is inside of combineDuplicateRecords it compares every record against every record, creating duplicates in the identities array. So identities will end up looking like:

[{
    id: "111",
    identities: [
      {
        id: "111"
      },
      {
        id: "111"
      },
      {
        id: "222"
      },
      {
        id: "222"
      },
      {
        id: "333"
      },
      {
        id: "333"
      }
    ]
}]

when I really want it to look like this:

[{
id: "111",
identities:[
      {
        id: "222"
      },
      {
        id: "333"
      }
    ]
}]

Code:

var requestRecords = [
      {
        vid: "12345",
        id: "12345",
        email: "[email protected]",
        firstName: "GrandFathering",
        lastName: "TestMN",
        postalCode: "55443-2410",
        phone: "123-456-7890",
        key: "1212"
      },
      {
        vid: "121212",
        id: "12222",
        email: "[email protected]",
        firstName: "NoMatch",
        lastName: "NoMatchFound",
        postalCode: "43233-2410",
        phone: "123-456-7890",
        key: "121233"
      },
      {
        vid: "111",
        id: "111",
        email: "[email protected]",
        firstName: "samebatch",
        lastName: "samebatch",
        postalCode: "5545",
        phone: "123-456-7890",
        key: "3333",
      },
      {
        vid: "222",
        id: "222",
        email: "[email protected]",
        firstName: "samebatch",
        lastName: "samebatch",
        postalCode: "5545",
        phone: "123-456-7890",
        key: "4444",
      },
      {
        vid: "333",
        id: "333",
        email: "[email protected]",
        firstName: "samebatch",
        lastName: "samebatch",
        postalCode: "5545",
        phone: "123-456-7890",
        key: "55",

      }
    ];


  combineDuplicateRecords = (arrayOfRecords, prefilter) => {
    const recordsToRemove = [];
    arrayOfRecords.forEach(firstRecord => {
      arrayOfRecords.forEach((secondRecord, index) => {
        if (
          firstRecord.firstName == secondRecord.firstName &&
          firstRecord.lastName == secondRecord.lastName &&
          firstRecord.dateOfBirth == secondRecord.dateOfBirth &&
          firstRecord.phone == secondRecord.phone &&
          firstRecord.postalCode == secondRecord.postalCode &&
          firstRecord.id !=
            secondRecord.id
        ) {
          const identities = [];
          let identity = {};
          this.preserveExisitingIdentities(secondRecord, identities);
          this.preserveExisitingIdentities(firstRecord, identities);
          identity = this.setIdentityDifferencesBetweenRecords(
            firstRecord,
            secondRecord,
            prefilter,
            identity
          );
          identities.push(identity);
          firstRecord["identities"] = identities;
          recordsToRemove.push(index);
        }
      });
    });

    [...new Set(recordsToRemove)].forEach(index => {
      arrayOfRecords.splice(index, 1);
    });
    return arrayOfRecords;
  };

    preserveExisitingIdentities = (record, identities) => {
    if (record.hasOwnProperty("identities")) {
      record.identities.forEach(identity => {
        identities.push(identity);
      });
    }
    return identities;
  };

    setIdentityDifferencesBetweenRecords = (
    firstIdentity,
    secondIdentity,
    prefilter,
    identity
  ) => {
    const differences = Diff(firstIdentity, secondIdentity, prefilter);
    let i = differences.length;
    while (i--) {
      if (differences[i].path[0] == "vid") {
        differences.splice(i, 1);
      }

      if (differences[i].path[0] == "identities") {
        differences.splice(i, 1);
      }
      //we only want to keep the differences so we remove kind D
      if (differences[i]?.kind == "D") {
        differences.splice(i, 1);
      }
    }
    differences.forEach(diff => {
      identity[diff.path[0]] = diff.lhs;
    });
    return identity;
  };
  console.log(JSON.stringify(combineDuplicateRecords(requestRecords)));
2
  • It looks like you've already done a ton of existing. Work. The easiest way to fix this with zero code modification is to just have a small algorithm to remove those duplicates based on the inner key. Do you need help writing it? Commented Mar 19, 2020 at 20:59
  • that'd be great. i'm also open to doing this a different way if there is a better approach and scrapping my initial idea. Commented Mar 19, 2020 at 21:02

1 Answer 1

1

grab each inner id and save them in a data structure, then use Array#find to find the entire object and insert it back into identities

const array = [
{
    id: "111",
    identities: [
        {
            id: "111"
        },
        {
            id: "111"
        },
        {
            id: "222"
        },
        {
            id: "222"
        },
        {
            id: "333"
        },
        {
            id: "333"
        }
    ]
}
]

const cleanObject = (obj) => {
const allIds = obj.identities.map(({ id }) => id)
const mainId = obj.id
const uniqueIds = new Set(allIds)
uniqueIds.delete(mainId)

const nextIdentities = [...uniqueIds].map(currId => {
    return obj.identities.find(({ id }) => currId === id)
})
obj.identities = nextIdentities
return obj
};

const el = array.map(entry => {
return cleanObject(entry)
})

console.log(el)

Sign up to request clarification or add additional context in comments.

3 Comments

i think id:111 should not be in inner array
In your first code snippet, that isn't valid javascript, so I made a few (wrong) assumptions as to what the structure is. Can you clean it up and show us exactly what it is?
@JoshAdams My assumptions were correct on the data structure, but it was actually a mistake on my interpretation of the expected output (whoops). Updated.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.