0

I have an array of objects which are set up like so:

   { code: 1
    description: "ARTICLES OF AGREEMENT"
    disciplineId: "d29b2d98-39c6-4350-3bd5-08dac6565a75"
    id: "783d6788-19f2-4cbd-79b3-08dac6565a77"
    projectSchedules: []
    r6Codes : []
    r7Codes: []
    scheduleMaterials: []

}

and so on for the rest of them. This is stored in an array called schedulesList.
In this array there will be objects which are identical apart from the disciplineId. What am I trying to do is remove the ones that are identical but don't have a specific disciplineId

I had tried to do this by creating an array of objects that I wanted to remove called scheduleToRemove and then do:

  for(let i = 0; i< schedulesToRemove.length; i++) {
    scheduleList.splice(scheduleList.indexOf(schedulesToRemove[i]));
  }

However, this is only removing one duplicate and the rest remain there. So is there a simpler way of going about this?

Edit:

So schedulesToRemove will have all the objects I need removed schedulesList, so for example, it contains:

   { code: 350
    description: "SUPPLY, FABRICATE AND ERECT LADDER RACK INCLUDING ALL ACCESSORIES"
    disciplineId: "eb89ae1d-db9a-41ee-3bdb-08dac6565a75"
    id: "87b19612-d03a-4ce0-79f5-08dac6565a77"
    projectSchedules: []
    r6Codes : []
    r7Codes: []
    scheduleMaterials: []
}

scheduleList will also have this but also one like:

   { code: 350
    description: "SUPPLY, FABRICATE AND ERECT LADDER RACK INCLUDING ALL ACCESSORIES"
    disciplineId: "2f33be5c-f3fa-4c50-3bda-08dac6565a75"
    id: "87b19612-d03a-4ce0-79f5-08dac6565a77"
    projectSchedules: []
    r6Codes : []
    r7Codes: []
    scheduleMaterials: []
}

So as you can see, they are both the exact same apart from disciplineId having a different value. So I would want to remove the first one but keep the second one

lross33
  • 91
  • 1
  • 10
  • scheduleList = scheduleList.filter(curItem => !scheduleList.find(item => curItem.id === item.id && !item.disciplineId)); or it should be && item.disciplineId !== curItem.disciplineId, depending on "What am I trying to do is remove the ones that are identical but don't have a specific disciplineId" which I didn't quite understand. Either way, list will filter out items that return false from the next statement which is list.find(your wanted clause). – chuftica Feb 24 '23 at 13:34
  • What is schedulesToRemove consist of? Can you please post an example of it? – CodeThing Feb 24 '23 at 13:34
  • Does this answer your question? [How to remove all duplicates from an array of objects?](https://stackoverflow.com/questions/2218999/how-to-remove-all-duplicates-from-an-array-of-objects) – A-Tech Feb 24 '23 at 13:37

3 Answers3

1

If the intent is to get a list of unique elements of schedulesList based on only the id property. (Like the title of the question suggests.) You can do the following:

const ids = new Set(); // temp variable to keep track of accepted ids
const uniqueSchedulesList = schedulesList.filter(({ id }) => !ids.has(id) && ids.add(id));

This answer uses an empty set instance. !ids.has(id) makes sure elements are only accepted in the result if they are not present in the ids set. If the first part of this expression is true then we move on to ids.add(id) which adds the current id to ids and returns the ids set (truthy). Meaning that it's included in the result.


If the intent is to remove elements of schedulesToRemove from schedulesList based on only the id property. You can do the following:

const ids = new Set(schedulesToRemove.map(({ id }) => id));
const filteredSchedulesList = schedulesList.filter(({ id }) => !ids.has(id));

This answer is very similar. Instead of adding ids as we iterate through schedulesList from the list itself, we collect the ids we want to remove upfront from filteredSchedulesList.

Both suggestions make use of a Set instance, filter() and object destructuring assignment (in arrow function parameters).

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • I used the second method you suggested and that solved my issue, thank you for that. It successfully removes the all the duplicates and not just 1 like my attempt did – lross33 Feb 24 '23 at 15:00
0

Once you have array of objects you want to delete in schedulesToRemove. Then you can filter original array, i.e:

const scheduleList = scheduleList.filter(schedule => !schedulesToRemove.includes(schedule));
fela
  • 679
  • 8
  • 7
  • I did try this but it just seems to copy everything over regardless? So nothing has actually been removed – lross33 Feb 24 '23 at 13:57
0

I believe your code is not working because:

  • object is reference in javascript i.e. ({} !== {})
  • because the objects are different (regardless of reference) so even if your code migrated to any language where {} === {} the code won't work

your code deletes 1 'copy' but actually the object in question deletes itself

 const scheludes = [{ code: 1,
    description: "ARTICLES OF AGREEMENT",
    disciplineId: "d29b2d98-39c6-4350-3bd5-08dac6565a75",
    id: "783d6788-19f2-4cbd-79b3-08dac6565a77",
    projectSchedules: [],
    r6Codes : [],
    r7Codes: [],
    scheduleMaterials: [],
}, { code: 2,
    description: "ARTICLES OF AGREEMENT",
    disciplineId: "d29b2d98-39c6-4350-3bd5-08dac6565a75",
    id: "783d6788-19f2-4cbd-79b3-08dac6565a77",
    projectSchedules: [],
    r6Codes : [],
    r7Codes: [],
    scheduleMaterials: [],
}, { code: 1,
    description: "ARTICLES OF AGREEMENT",
    disciplineId: "d29b2d99-39c6-4350-3bd5-08dac6565a75",
    id: "783d6788-19f2-4cbd-79b3-08dac6565a77",
    projectSchedules: [],
    r6Codes : [],
    r7Codes: [],
    scheduleMaterials: [],
}, { code: 1,
    description: "ARTICLES OF AGREEMENT",
    disciplineId: "d29b2d99-49c6-4350-3bd5-08dac6565a75",
    id: "783d6788-19f2-4cbd-79b3-08dac6565a77",
    projectSchedules: [],
    r6Codes : [],
    r7Codes: [],
    scheduleMaterials: [],
}]


function equalSchelude(sche1, sche2) {
  const props1 = Object.keys(sche1)
  const props2 = Object.keys(sche2)
  
  if (props1.length !== props2.length) return false
  
  return props1.every(prop => {
    if (prop === "disciplineId") return true
    
    if (typeof sche1[prop] === "object")
      return equalSchelude(sche1[prop], sche2[prop])
    return sche1[prop] === sche2[prop]
  })
}

for (let i = 1; i < scheludes.length; i++) {
  i -= scheludes.splice(
    scheludes
      .slice(0, i)
      .findIndex(item => equalSchelude(item, scheludes[i])) >>> 0,
    1
  ).length
}

console.log(scheludes)
Tachibana Shin
  • 2,605
  • 1
  • 5
  • 9