Initially I was trying to do a switch but in the next lines I will explain why it didn't work like that.
Having two arrays like those ones:
const countries = [ 'France', 'Italy', 'Spain' ];
const cities = [ 'Paris', 'Marseille', 'Rome', 'Naples', 'Milan', 'Madrid' ];
As you can see, there is a connection between the countries and the cities:
- France has Paris and Marseille
- Italy has Rome, Naples and Milan
- Spain has Madrid
The logic of my application should check for those countries alphabetically, (F > I > S), then check if the available city.
If there is a country present but no city was provided, as default it should use the capital city (first from the list). If there are multiple cities, the capital should be checked for the last one.
Examples:
Input: countries = [ 'France' ]; cities = [ 'Marseille']
Result: doThis('Marseille');
Input: countries = [ 'France' ]; cities = []
Result: doThis('Paris');
Input: countries = [ 'France' ]; cities = [ 'Paris', 'Marseille']
Result: doThis('Marseille');
Here is the code:
const doThat = (city: string) => {
console.log(city);
};
const myFunc = (countries: string[], cities: string[]) => {
if (countries.includes('France')) {
if (cities.includes('Marseille')) {
doThat('Marseille');
} else doThat('Paris');
} else if (countries.includes('Italy')) {
if (cities.includes('Naples')) {
doThat('Naples');
} else if (cities.includes('Milan')) {
doThat('Naples');
} else doThat('Rome');
} else if (countries.includes('Spain')) {
doThat('Madrid');
} else doThat('empty');
};
It cannot work with a switch because it would be something like:
switch (countries) {
case countries.includes('France'): ... // cannot be boolean here
...
}
Is there a way to make it better/more readable?
CodePudding user response:
Here's an article I wrote about it! Refactoring with maps
Long story short: use Map
s! In your specific case you may want a map of <string, string[]>
.
So that in your code you will have:
for(country in countries){
const mappedCities = contryMap.get(country)
// find either the first city which is in both the passed array and the map
// or default to the first one
const cityIndex = Math.max(0, mappedCities.findIndex(city =>
cities.includes(city)))
doThat(mappedCities[cityIndex]
}
and in a separate file:
export const cityMap = new Map<string, string[]>([
['france', ['Paris', 'Marseille']],
])
CodePudding user response:
For that purpose, you would need a loop and iterate through the arrays, and nest the switch case statements inside the loop. Inside the switch case statements, you would need another loop for cities
and again another switch case statement like so.
const myFunc = (countries: string[], cities: string[]) => {
for(const country of countries) {
switch(country) {
case "France": {
// If the list of cities is empty i.e.
// If no cities are provided, use the capital city
if(cities.length === 0) {
doThat("Paris");
break;
}
for(const city of cities) {
switch(city){
// Look for other cities first
case "Marseille":
doThat("Marseille");
break;
default:
// And the capital city last
doThat("Paris");
break;
}
}
break;
};
case "Italy": {
// If no cities are provided, use the capital city
if(cities.length === 0) {
doThat("Rome");
break;
}
for(const city of cities) {
switch(city) {
// Look for other cities first
case "Naples":
return doThat("Naples");
case "Milan":
return doThat("Milan")
default:
// And the capital city last
return doThat("Rome");
}
}
break;
};
case "Spain": {
// Since there is only one city (i.e. the capital) for Spain
doThat("Madrid")
break;
}
default:
// If no matching country is passed, send "empty"
doThat("empty");
break;
}
}
};