【问题标题】:Determine the number of enum elements TypeScript确定枚举元素的数量 TypeScript
【发布时间】:2016-10-28 07:54:00
【问题描述】:

如标题所述,如何确定 Typescript 中枚举中的元素数量,例如本例中

enum ExampleEnum {

    element1 = 1,
    element2 = 2,
    element3 = 3,
    element4 = 4,
    element5 = 5,
    element6 = 6

}

var exampleEnumElementCount:number = ? 

如何确定计数?在这种情况下,它应该是 6

【问题讨论】:

    标签: typescript enums


    【解决方案1】:

    Typescript 没有提供获取枚举元素数量的标准方法。但鉴于enum reverse mappingthe implementation,以下工作:

    Object.keys(ExampleEnum).length / 2
    

    注意,对于string enums,您不要除以零,因为不会生成反向映射属性:

    Object.keys(StringEnum).length;
    

    具有混合字符串和数值的枚举可以通过以下方式计算:

    Object.keys(ExampleEnum).filter(isNaN).length
    

    【讨论】:

    • 为什么要除以 2?
    • 这个答案很危险。字符串枚举会失败。
    • 这个答案不再正确。 Object.keys(ExampleEnum) / 2 现在不需要除以二。使用 Typescript v3 甚至可以很好地支持字符串,就像数字一样。 @MarkusEnde
    • @IlkerCat 关于 TypeScript v3 中的这个问题没有任何改变 - 带有数字的枚举仍然有两倍的键,因为它们得到了反向映射,而字符串枚举没有得到反向映射,所以你不要不需要除以二。运行时实现的这种差异一直存在并且仍然存在。请注意,您也可以使用混合枚举。在这种情况下,枚举成员的数量介于一半和全长之间,可以使用 Object.keys(ExampleEnum).filter(isNaN).length 精确计算(您也可以在此处使用 Object.values),仅计算非-数字项目。
    【解决方案2】:

    如果您有一个从0 开始计数的枚举,您可以插入一个占位符作为最后一个元素的大小,如下所示:

    enum ERROR {
      UNKNOWN = 0,
      INVALID_TYPE,
      BAD_ADDRESS,
      ...,
      __LENGTH
    }
    

    然后使用ERROR.__LENGTH 将是枚举的大小,无论您插入多少元素。

    对于任意偏移量,您可以跟踪它:

    enum ERROR {
      __START = 7,
      INVALID_TYPE,
      BAD_ADDRESS,
      __LENGTH
    }
    

    在这种情况下,有意义的错误数量将是ERROR.__LENGTH - (ERROR.__START + 1)

    【讨论】:

      【解决方案3】:

      接受的答案在任何附加了值的枚举版本中都不起作用。它仅适用于最基本的枚举。这是我的适用于所有类型的版本:

      export function enumElementCount(enumName: any): number {
          let count = 0
          for(let item in enumName) {
              if(isNaN(Number(item))) count++
          }
          return count
      }
      

      这里是 mocha 的测试代码:

      it('enumElementCounts', function() {
          enum IntEnum { one, two }
          enum StringEnum { one = 'oneman', two = 'twoman', three = 'threeman' }
          enum NumberEnum { lol = 3, mom = 4, kok = 5, pop = 6 }
          expect(enumElementCount(IntEnum)).to.equal(2)
          expect(enumElementCount(StringEnum)).to.equal(3)
          expect(enumElementCount(NumberEnum)).to.equal(4)
      })
      

      【讨论】:

        【解决方案4】:

        为了进一步扩展@Esqarrouth 的答案,枚举中的每个值都会产生两个键,字符串枚举值除外。例如,给定 TypeScript 中的以下枚举:

        enum MyEnum {
            a = 0, 
            b = 1.5,
            c = "oooo",
            d = 2,
            e = "baaaabb"
        }
        

        转译成 Javascript 后,你会得到:

        var MyEnum;
        (function (MyEnum) {
            MyEnum[MyEnum["a"] = 0] = "a";
            MyEnum[MyEnum["b"] = 1.5] = "b";
            MyEnum["c"] = "oooo";
            MyEnum[MyEnum["d"] = 2] = "d";
            MyEnum["e"] = "baaaabb";
        })(MyEnum || (MyEnum = {}));
        

        如您所见,如果我们只是有一个带有 a 条目的枚举,并给定一个 0 的值,那么您最终会得到两个键; MyEnum["a"]MyEnum[0]。另一方面,字符串值只需生成一个键,如上面的条目ce 所示。

        因此,您可以通过确定有多少个Key不是数字来确定实际计数;即,

        var MyEnumCount = Object.keys(MyEnum).map((val, idx) => Number(isNaN(Number(val)))).reduce((a, b) => a + b, 0);
        

        它只是简单地映射所有键,如果键是字符串则返回1,否则返回0,然后使用reduce函数添加它们。

        或者,一种更容易理解的方法:

        var MyEnumCount = (() => {
            let count = 0;
            Object.keys(MyEnum).forEach((val, idx) => {
                if (Number(isNaN(Number(val)))) {
                    count++;
                }
            });
            return count;
        })();
        

        你可以在 TypeScript 操场上自己测试https://www.typescriptlang.org/play/

        【讨论】:

          猜你喜欢
          • 2018-05-27
          • 1970-01-01
          • 1970-01-01
          • 2010-10-17
          • 2020-11-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-22
          相关资源
          最近更新 更多