I have an object which has a property called tier
which has 9 possible values - IRON, BRONZE, SILVER, GOLD, PLATINUM, DIAMOND, MASTER, GRANDMASTER and CHALLENGER
.
Based on that property, I want to display the emblem corresponding to the tier, however, whilst the tier might be called IRON
, the image file with the emblem would be called Emblem_Iron
.
This is why I've created a function which takes a tier
as an argument and then returns the file name of the emblem image corresponding to the tier
so that I could do this:
<img class='ranked-emblem' :src="'../emblems/' + rankedEmblem(league.tier) + '.png'" alt="">
And my function is:
rankedEmblem(tier){
if (tier === 'IRON') {
return 'Emblem_Iron'
} else if (tier === 'BRONZE') {
return 'Emblem_Bronze'
} else if (tier === 'SILVER') {
return 'Emblem_Silver'
} else if (tier === 'GOLD') {
return 'Emblem_Gold'
} else if (tier === 'PLATINUM') {
return 'Emblem_Platinum'
} else if (tier === 'DIAMOND') {
return 'Emblem_Diamond'
} else if (tier === 'MASTER') {
return 'Emblem_Master'
} else if (tier === 'GRANDMASTER') {
return 'Emblem_Grandmaster'
} else if (tier === 'CHALLENGER') {
return 'Emblem_Challenger'
}
}
While this works completely fine, I was wondering if there's a more elegant way of doing this that would shorten the function and maybe remove a couple of if els.
I have an object which has a property called tier
which has 9 possible values - IRON, BRONZE, SILVER, GOLD, PLATINUM, DIAMOND, MASTER, GRANDMASTER and CHALLENGER
.
Based on that property, I want to display the emblem corresponding to the tier, however, whilst the tier might be called IRON
, the image file with the emblem would be called Emblem_Iron
.
This is why I've created a function which takes a tier
as an argument and then returns the file name of the emblem image corresponding to the tier
so that I could do this:
<img class='ranked-emblem' :src="'../emblems/' + rankedEmblem(league.tier) + '.png'" alt="">
And my function is:
rankedEmblem(tier){
if (tier === 'IRON') {
return 'Emblem_Iron'
} else if (tier === 'BRONZE') {
return 'Emblem_Bronze'
} else if (tier === 'SILVER') {
return 'Emblem_Silver'
} else if (tier === 'GOLD') {
return 'Emblem_Gold'
} else if (tier === 'PLATINUM') {
return 'Emblem_Platinum'
} else if (tier === 'DIAMOND') {
return 'Emblem_Diamond'
} else if (tier === 'MASTER') {
return 'Emblem_Master'
} else if (tier === 'GRANDMASTER') {
return 'Emblem_Grandmaster'
} else if (tier === 'CHALLENGER') {
return 'Emblem_Challenger'
}
}
While this works completely fine, I was wondering if there's a more elegant way of doing this that would shorten the function and maybe remove a couple of if els.
Share Improve this question asked Jul 30, 2019 at 14:46 OnyxOnyx 5,78210 gold badges52 silver badges119 bronze badges 7 | Show 2 more comments5 Answers
Reset to default 10You can use a plain Object
as a map.
var emblems = {
IRON: "Emblem_Iron",
BRONZE: "Emblem_Bronze",
SILVER: "Emblem_Silver",
GOLD: "Emblem_Gold",
PLATINUM: "Emblem_Platinum",
DIAMOND: "Emblem_Diamond",
MASTER: "Emblem_Master",
GRANDMASTER: "Emblem_Grandmaster",
CHALLENGER: "Emblem_Challenger"
};
function rankedEmblem(tier) {
// Could also help user by doing: emblems[tier.toUpperCase()]
return emblems[tier] || "No_Emblem";
}
console.log(rankedEmblem("GOLD"));
console.log(rankedEmblem("PLATINUM"));
You can use String concatination and functions like so:
function rankedEmblem(tier){
return "Emblem_" + tier.charAt(0).toUpperCase() + tier.slice(1).toLowerCase();
}
console.log(rankedEmblem("CHALLENGER"));
rankedEmblem(tier){
let myEmblems = {IRON: 'Emblem_Iron', BRONZE: 'Emblem_Bronze' };
//You can put whatever emblem you want as key:value pair
return myEmblems[tier];
}
rankedEmblem(tier) {
return 'Emblem_' + tier.substr(0, 1) + tier.substr(2).toLowerCase();
}
You're in Javascript: use an object. There is no reason for if
or which
when you know what the mapping is:
// this mapping will probably live in its own file
const mapping = {
IRON: `emblem-Iron.png`,
GOLD: `emblem-Gold.png`,
...
}
// this function will probably _also_ live in its own file,
// and import that mapping (either with import or require).
function getImageForTier(tier) {
let tierImage = mapping[tier];
if (!tierImage) {
// ... somehow, your code allowed for an unknown tier to make it this far.
console.error(`unknown tier ${tier}!`);
return UNKNOWN_TIER_IMAGE;
}
return tierImage;
}
You could use a function to just blindly generate the image filename based on the tier string, but then you run into the problem of "what about if the tier is actually wrong/unknown?".
If you already validate the tier somewhere earlier, then you don't even need a function, a template string will let you do this. But then at least make sure all your image filenames are in lowercase, because you should be able to rely on assets existing, and having to worry about "are there supposed to be capital letters in this file?" makes a dev life unnecessarily difficult:
image.src = `${baselocation}/ember-${tier.toLowerCase()}.png`
switch/case
seems like the obvious choice. Also, string interpolation after putting thetier
into Pascalcase is another option. – user47589 Commented Jul 30, 2019 at 14:48tier
is a number, an array of strings indexed bytier
would work. If it's a string, an object orMap
will do. – kshetline Commented Jul 30, 2019 at 14:50tier
is a string. OP is comparing it against various strings. – user47589 Commented Jul 30, 2019 at 14:51