Cleaning Data - Vincentvanleeuwen/frontend-data GitHub Wiki
While going through the merged data, I've found multiple entries in the location column that didn't exactly show what I wanted it to show. Therefore I made a list of these incorrect entries, and created a function to fix or filter these entries. These are all the incorrect entries:
- Almere Buiten → Almere
- Almere Stad → Almere
- Garage Maasburg → Maasburg
- Ziekenhuis) (Rotterdam → Rotterdam
- Heerhugowaard Centrum → Heerhugowaard
- Garage Oostwal-Oost → Oss
- Parkeergarage Emmawijk - Dek → Zwolle
- utrecht → Utrecht
- Garage Boschplein → Sneek
- haarlem → Haarlem
- Parkeergarage Station → DELETE
- Carpool Nuenen A270 → DELETE
I started by looking around for a fix to make cities start with a capital letter. I found a great example on stack overflow that I could use.
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
console.log(capitalizeFirstLetter('foo')); // Foo
This piece of code checks the first letter in a string, and capitalizes it.
For the rest of the data I've decided to use a switch. It checks every value, and if it matches a case it'll change that value to the correct value.
Now I can finally start with restructuring the data set. I started by changing everything from an array to an object.
export const restructureDataSets = (arr) => {
return arr.reduce((acc, cur, i) => {
// -- 0:{ areaid: '', charginpoint: '', geoloc: ''} // Location, capacity, and chargingPoints
let location = cur[3][1];
let capacity = +cur[0][1];
let chargingPoints = +cur[1][1];
//If location doesn't exist
if (!acc[location]) {
// Add location
acc[location] = {capacity: 0, chargingPointCapacity: 0}
}
// Add capacity and chargingPointCapacity to location
acc[location].capacity += capacity;
acc[location].chargingPointCapacity += chargingPoints;
return acc;
}, {});
};
Next I wanted to try to split the datasets in two parts, one part being full of cities, and the other full of towns.
export const restructureDataSets = (arr) => {
return arr.reduce((acc, cur, i) => {
// Location, capacity, and chargingPoints
let location = cur[3][1];
let capacity = +cur[0][1];
let chargingPoints = +cur[1][1];
acc = {cities: {}, towns: {}};
//If location doesn't exist
if(!acc.cities.location) {
if(cities.includes(location)) {
acc.cities[location] = { capacity: 0, chargingPointCapacity: 0};
acc.cities[location].capacity += capacity;
acc.cities[location].chargingPointCapacity += chargingPoints;
} else {
acc.towns[location] = { capacity: 0, chargingPointCapacity: 0};
acc.towns[location].capacity += capacity;
acc.towns[location].chargingPointCapacity += chargingPoints;
}
}
// Add capacity and chargingPointCapacity to location
return acc;
}, {});
};
This didn't seem to work as I want because every time an entry goes through the reduce function, I'm setting accumulator back to an empty object with city and towns in it.
After a lot of trial and error, Jonah advised me to make use of .find() just like I did in my Merge function. The way I'm getting the location, capacity and chargingPoints is correct. I'm getting the correct values from those variables.
I wanted the reduce function to merge city with a double entry. So I created a findIndex function that looked for items with the same location, and returned the index of this item to the variable "itemIndex". To check if this item exists, I checked if itemIndex is higher than -1. If it's -1 it means it doesn't exist. If it exists, I'm only pushing the amount of capacity and chargingPoints to the existing item. Otherwise I'm creating a new object and adding it directly to the accumulator.
export const restructureDataSets = (arr) => {
console.log(arr);
return arr.reduce((acc, cur) => {
let location = cur[3][1];
let capacity = +cur[0][1];
let chargingPoints = +cur[1][1];
// Check if location matches another entries' location, return the index
const itemIndex = acc.findIndex(item => item.location === location);
// Check if index exists
if(itemIndex > -1) {
// Add capacity/chargingpointcapacity to this object
acc[itemIndex].capacity += capacity;
acc[itemIndex].chargingPointCapacity += chargingPoints;
} else {
// Otherwise create a new entry
const newItem = {
location: null,
capacity: 0,
chargingPointCapacity: 0,
type: null
};
// Add capacity, chargingPointCapacity, and location to entry
newItem.location = location;
newItem.capacity += capacity;
newItem.chargingPointCapacity += chargingPoints;
// Set the type of the entry
if (!newItem.type) {
// Check if town or city
if (cities.includes(location)) {
newItem.type = 'city';
} else {
newItem.type = 'town';
}
}
acc.push(newItem);
}
return acc;
}, []);
};