最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a more elegant way of writing a function that returns the name of an image based on the argument of the fu

programmeradmin1浏览0评论

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
  • 1 switch/case seems like the obvious choice. Also, string interpolation after putting the tier into Pascalcase is another option. – user47589 Commented Jul 30, 2019 at 14:48
  • hashmap object is an alternative. So is string parser – charlietfl Commented Jul 30, 2019 at 14:48
  • 2 It looks like the output is straightforwardly buildable from the input. Isn't it just capitalize and prepend Emblem_? – danh Commented Jul 30, 2019 at 14:49
  • If tier is a number, an array of strings indexed by tier would work. If it's a string, an object or Map will do. – kshetline Commented Jul 30, 2019 at 14:50
  • @kshetline tier is a string. OP is comparing it against various strings. – user47589 Commented Jul 30, 2019 at 14:51
 |  Show 2 more comments

5 Answers 5

Reset to default 10

You 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`

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论