重构JavaScript / TypeScript:消除重复的代码块

时间:2019-03-28 10:53:05

标签: javascript typescript switch-statement refactoring

如何缩短这个怪物块? (非阵列解决方案)

setFooTypeFlag(flag: string) {
  switch (flag) {
    case 'a':
      this.fooType.a = true;  
      this.fooType.b = false;
      this.fooType.c = false;
      this.fooType.d = false;
      break;
    case 'b'
      this.fooType.a = false;
      this.fooType.b = true;
      this.fooType.c = false;
      this.fooType.d = false;
      break;
    case 'c':
      this.fooType.a = false;
      this.fooType.b = false;
      this.fooType.c = true;
      this.fooType.d = false;
      break;
    case 'd':
      this.fooType.a = false;
      this.fooType.b = false;
      this.fooType.c = false;
      this.fooType.d = true;
      break;
  }
}

4 个答案:

答案 0 :(得分:3)

对你来说足够短了吗? :)

基本上,迭代每个键,然后将所有内容都设置为flag === key:)

setFooTypeFlag(flag: string) {
  Object.keys(this.fooType).forEach(key => {
      this.fooType[key] = flag === key;
  });
}

如果this开头没有键,请参阅answer of Jack

答案 1 :(得分:1)

使用动态属性名称。这将适用于任何可能性,并且不需要您预先将它们全部初始化:

setFooTypeFlag(flag: string) {
  var chars = ["a", "b", "c", "d"];
  for (var i = 0; i < chars.length; i++) {
    this.fooType[chars[i]] = chars[i] == flag;
  }
}

答案 2 :(得分:1)

enum fooTypes {
  "a" = "a",
  "b" = "b",
  "c" = "c",
  "d" = "d"
}

interface IFooFlags {
  [key: string]: boolean;
}

const defaultFooTypes = new Map<fooTypes, boolean>([
  [fooTypes.a, true],
  [fooTypes.b, true],
  [fooTypes.c, true],
  [fooTypes.d, true]
]);

const fooTypesMappings = new Map<fooTypes, boolean[]>([
  [fooTypes.a, [true, false, false, false]],
  [fooTypes.b, [false, true, false, false]],
  [fooTypes.c, [false, false, true, false]],
  [fooTypes.d, [false, false, false, true]]
]);

class MyClass {
  private mappings = fooTypesMappings;
  private fooTypes = defaultFooTypes;

  private setFooTypes(values: boolean[]): void {
    [...this.fooTypes.keys()].forEach((key, index) =>
      this.fooTypes.set(key, values[index])
    );
  }

  // In modern engines you can return:
  // Object.fromEntries(this.fooTypes)
  public getFooTypes(): IFooFlags {
    return [...this.fooTypes].reduce(
      (obj, { 0: key, 1: val }) => ({ ...obj, [key]: val }),
      {}
    );
  }

  public setFooTypeFlag(flag: fooTypes): void {
    const flagTypes = this.mappings.get(flag);
    if (!flagTypes) {
      throw new Error("Invalid flag type");
    }
    this.setFooTypes(flagTypes);
  }
}

const fooLover = new MyClass();
fooLover.setFooTypeFlag(fooTypes.d);
alert(JSON.stringify(fooLover.getFooTypes()));

Here is a demo of it

答案 3 :(得分:1)

我也从@ jack-bashford的答案中得到启发:

.pause-animation{
    animation-play-state: paused;
}

Here is the demo