I have an array of what I call fareZone
objects. Each fare zone object has an array of stops
.
I wish to keep the first occurrence of a stop
object and remove all other occurrences of the same object (same meaning it has the same atcoCode
) from the array.
Object Array
const fareZones = [{
name: 'Zone 1',
stops: [{
stopName: 'Ashton Bus Station',
atcoCode: '1800EHQ0081',
},
{
stopName: 'New Street',
atcoCode: '1800EHQ0721',
},
{
stopName: 'Farfield Road',
atcoCode: '1800EHQ0722',
},
{
stopName: 'Ashton Bus Station',
atcoCode: '1800EHQ0081',
},
{
stopName: 'New Street',
atcoCode: '1800EHQ0041',
},
],
prices: [],
},
{
name: 'Zone 2',
stops: [{
stopName: 'Henrietta Street',
atcoCode: '1800EH24201',
}, ],
prices: [],
},
{
name: 'Zone 3',
stops: [{
stopName: 'Crickets Ln',
atcoCode: '1800EH24151',
},
{
stopName: 'Tameside College',
atcoCode: '1800EH21241',
},
{
stopName: 'Ashton Bus Station',
atcoCode: '1800EHQ0081',
},
],
prices: [],
}]
Desired outcome
const fareZones = [{
name: 'Zone 1',
stops: [{
stopName: 'Ashton Bus Station',
atcoCode: '1800EHQ0081',
},
{
stopName: 'New Street',
atcoCode: '1800EHQ0721',
},
{
stopName: 'Farfield Road',
atcoCode: '1800EHQ0722',
},
{
stopName: 'New Street',
atcoCode: '1800EHQ0041',
},
],
prices: [],
},
{
name: 'Zone 2',
stops: [{
stopName: 'Henrietta Street',
atcoCode: '1800EH24201',
}, ],
prices: [],
},
{
name: 'Zone 3',
stops: [{
stopName: 'Crickets Ln',
atcoCode: '1800EH24151',
},
{
stopName: 'Tameside College',
atcoCode: '1800EH21241',
},
{
stopName: 'Ashton Bus Station',
atcoCode: '1800EHQ0081',
},
],
prices: [],
}]
Notice how the third stop in Zone 1 was removed because it was a duplicate.
How do I achieve this in JavaScript?
Current Progress
// for each fare stage, check to see if we have duplicate stops
fareZones.map((fz) => {
let stopsWithinFareZone = fz.stops;
const atcoCodesOfStopsWithinFareZone = stopsWithinFareZone.map((s) => s.atcoCode);
const hasDuplicateStops = hasDuplicates(atcoCodesOfStopsWithinFareZone);
if (hasDuplicateStops) {
// so we have duplicates, how do I keep the first occurrence
// and remove all other occurrences of the duplicate stop
}
});
export const hasDuplicates = (array: string[]): boolean => {
return new Set(array).size !== array.length;
};
CodePudding user response:
You can easily achieve the result using Set
and filter
as:
const result = fareZones.map((fareZone) => {
const set = new Set();
const stops = fareZone.stops.filter((o) => {
if (!set.has(o.atcoCode)) {
set.add(o.atcoCode);
return true;
} else return false;
});
return { ...fareZone, stops };
});
const fareZones = [
{
name: "Zone 1",
stops: [
{
stopName: "Ashton Bus Station",
atcoCode: "1800EHQ0081",
},
{
stopName: "New Street",
atcoCode: "1800EHQ0721",
},
{
stopName: "Farfield Road",
atcoCode: "1800EHQ0722",
},
{
stopName: "Ashton Bus Station",
atcoCode: "1800EHQ0081",
},
{
stopName: "New Street",
atcoCode: "1800EHQ0041",
},
],
prices: [],
},
{
name: "Zone 2",
stops: [
{
stopName: "Henrietta Street",
atcoCode: "1800EH24201",
},
],
prices: [],
},
{
name: "Zone 3",
stops: [
{
stopName: "Crickets Ln",
atcoCode: "1800EH24151",
},
{
stopName: "Tameside College",
atcoCode: "1800EH21241",
},
{
stopName: "Ashton Bus Station",
atcoCode: "1800EHQ0081",
},
],
prices: [],
},
];
const result = fareZones.map((fareZone) => {
const set = new Set();
const stops = fareZone.stops.filter((o) => {
if (!set.has(o.atcoCode)) {
set.add(o.atcoCode);
return true;
} else return false;
});
return { ...fareZone, stops };
});
console.log(result);