typescript 更好的(功能)替代JS中的多个开关案例

deyfvvtc  于 2022-11-26  发布在  TypeScript
关注(0)|答案(4)|浏览(156)

Object Lookup方法在JS中非常流行,可以更好地替代Switch-case语句,例如:

function phoneticLookup(val) {
  var result = "";

  switch(val) {
    case "alpha":
      result = "Adams";
      break;
    case "bravo":
      result = "Boston";
      break;
    case "charlie":
      result = "Chicago";
      break;
  }
  return result;
}

function phoneticLookup(val) {
  var result = "";

  var lookup = {
    "alpha": "Adams",
    "bravo": "Boston",
    "charlie": "Chicago",
  };

  result = lookup[val];
  return result;
}

但是如果switch的情况像下面这样,你可以看到多个case返回相同的结果。我们如何用objectsmap,或者其他任何方式(不使用if-else)在JS中更好地编写它呢?

let continent = '';
switch (country) {
   case "China":
   case "India":
   case "Nepal": 
       continent = 'Asia';
       break;
   case "UK":
   case "France":
   case "Poland": 
       continent = 'Europe';
       break;
   case "Egypt":
   case "Zimbave":
   case "Somalia": 
       continent = 'Africa';
       break;
   default: 
       continent = 'Other'
       break;
}
zengzsys

zengzsys1#

我建议不要引入任何抽象。你可以通过把你的 switch 隐藏在一个函数中来使它起作用(不需要看函数的内部)。
在您已经拥有的基础上,唯一的建议是使用 return,而不是变异一个var然后中断。

const whichContinent = (country) => {
  switch (country) {
   case "China":
   case "India":
   case "Nepal": 
     return 'Asia';

   case "UK":
   case "France":
   case "Poland": 
     return 'Europe';

   case "Egypt":
   case "Zimbave":
   case "Somalia": 
     return 'Africa';

   default: 
     return 'Unknown'
  }
}

console.log(
  whichContinent('hogwarts'),
);
svdrlsy4

svdrlsy42#

你有几个选择。pattern matching propsal是第一阶段,可能永远不会成为标准。你可以像this answer那样写一个自定义的switch/match函数。对于这个特定的情况,你实际上可以使用对象查找,只是有点不同:

const continents = {
  "Africa": ["Egypt", "Ghana"], // etc
  "Asia": ["China", "Bhutan"], // etc
}

const assignContinent = (country) => {
  const possibleMatch = Object.entries(continents)
    .find((continent) => continent[1].includes(country))
  return possibleMatch ? possibleMatch[0] : "Other"
}
kjthegm6

kjthegm63#

为了提高性能,我建议定义一个重复大陆的Map:

countryToContinentMap = {
   China:   'Asia',
   India:   'Asia',
   Nepal:   'Asia',
   UK:      'Europe',
   France:  'Europe',
   Poland:  'Europe',
   Egypt:   'Africa',
   Zimbave: 'Africa',
   Somalia: 'Africa'
}

function getContinent(country) {
    return countryToContinentMap[country] || 'Other';
}

console.log('Nepal => ' + getContinent('Nepal'));
console.log('Xomur => ' + getContinent('Xomur'));

输出量:

Nepal => Asia
Xomur => Other

为了更容易定义Map,您可以像@Zac Anger那样做,然后在使用之前通过编程反转Map一次。

gfttwv5a

gfttwv5a4#

如果您想坚持使用您的对象查找版本,最简单的方法之一就是创建一个以国家为值、以洲为键的对象。然后动态创建一个以洲为值、以国家为键的对象。

const continents = {
   "Asia": ["China", "India", "Nepal"],
   "Europe": ["UK", "France", "Poland"],
   "Africa": ["Egypt", "Zimbabwe", "Somalia"],
};

let countryContinent = {};

for(const [continent, countries] of Object.entries(continents)){
//Merge countryContinent with newly created object with countries as keys and for each key value equal to continent
   countryContinent = Object.assign(countryContinent, Object.fromEntries(countries.map(country =>[country, continent])));
}

现在作为countryContinent对象看起来像这样:

{
  'China': 'Asia',
  'India': 'Asia',
  'Nepal': 'Asia',
  'UK': 'Europe',
  'France': 'Europe',
  'Poland': 'Europe',
  'Egypt': 'Africa',
  'Zimbabwe': 'Africa',
  'Somalia': 'Africa'
}

你可以在上面自由使用你的phoneticLookup函数。

相关问题