如何从枚举中获取一个随机项?
enum Colors {
Red, Green, Blue
}
function getRandomColor(): Color {
// return a random Color (Red, Green, Blue) here
}
如何从枚举中获取一个随机项?
enum Colors {
Red, Green, Blue
}
function getRandomColor(): Color {
// return a random Color (Red, Green, Blue) here
}
function randomEnum<T>(anEnum: T extends object): T[keyof T] {
const enumValues = Object.keys(anEnum)
.map(n => Number.parseInt(n))
.filter(n => !Number.isNaN(n)) as unknown as T[keyof T][]
const randomIndex = Math.floor(Math.random() * enumValues.length)
const randomEnumValue = enumValues[randomIndex]
return randomEnumValue;
}
像这样使用:
interface MyEnum {X, Y, Z}
const myRandomValue = randomEnum(MyEnum)
myRandomValue
的类型将是 MyEnum
。
大多数上面的答案都返回枚举键,但我们真正关心的不是枚举值吗?
如果您正在使用lodash,那么这实际上非常简单:
_.sample(Object.values(MyEnum))
如果你不使用lodash,或者你希望这个函数独立存在,我们可以通过修改@Steven Spungin的答案来实现类型安全的随机枚举:
function randomEnum<T>(anEnum: T): T[keyof T] {
const enumValues = (Object.values(anEnum) as unknown) as T[keyof T][];
const randomIndex = Math.floor(Math.random() * enumValues.length);
return enumValues[randomIndex];
}
myEnum
是什么? - vivekmoreObject.values(myEnum)
函数返回了一个混合了字符串和数字的数组,例如 ['Red', 'Green', 'Blue', 0, 1, 2]
。这在上述 Colors 枚举中是非常奇怪的。而 Object.keys
函数也会返回类似的结果,只不过其中的数字也会被转换成字符串:['Red', 'Green', 'Blue', '0', '1', '2']
。 - Lewy Blue所以对我来说,没有任何答案可用,最终我做成了这样:
有以下枚举类型:
export enum Jokenpo {
PAPER = 'PAPER',
ROCK = 'ROCK',
SCISSOR = 'SCISSOR',
}
const index= Math.floor(Math.random() * Object.keys(Jokenpo).length);
const value= Object.values(Jokenpo)[index];
return Jokenpo[value];
我只是从枚举类型中随机获取一个值,然后将其用于转换为真实值。
你觉得这个怎么样,使用es2017中的Object.values函数(不支持IE浏览器,在其他浏览器中的支持较为最新):
function randEnumValue<T>(enumObj: T): T[keyof T] {
const enumValues = Object.values(enumObj);
const index = Math.floor(Math.random() * enumValues.length);
return enumValues[index];
}
const randomEnumKey = enumeration => {
const keys = Object.keys(enumeration)
.filter(k => !(Math.abs(Number.parseInt(k)) + 1));
const enumKey = keys[Math.floor(Math.random() * keys.length)];
return enumKey;
};
获取一个随机值:
const randomEnumValue = (enumeration) => enumeration[randomEnumKey(enumeration)];
MyEnum[randomEnumKey(MyEnum)]
Example:
const randomEnumKey = <T>(enumeration: T): keyof T => {
... https://stackblitz.com/edit/typescript-random-enum-nfk4ab?file=index.ts - Adam D这是我能想到的最好方法,但看起来像是一个hack,并依赖于TypeScript中enum
的实现方式,我不确定它是否保证保持不变。
假设有这样一个枚举:
enum Color { Red, Green, Blue }
console.log
来输出它,我们将得到以下输出结果。{
'0': 'Red',
'1': 'Green',
'2': 'Blue',
Red: 0,
Green: 1,
Blue: 2,
}
const enumValues = Object.keys(Color)
.map(n => Number.parseInt(n))
.filter(n => !Number.isNaN(n))
enumValues
现在是[0, 1, 2]
。我们现在只需要随机选择其中一个值。有一个很好的函数实现可以返回两个值之间的随机整数,这正是我们需要的,以便随机选择索引。const randomIndex = getRandomInt(0, enumValues.length)
const randomEnumValue = enumValues[randomIndex]
TS2322:类型“number”不能分配给类型“Color”
。 - jarodsmk编辑:修正了类型问题。
稍微整理一下@ShailendraSingh的答案,如果枚举如问题中所定义,没有任何自定义索引,那么这是一个简单的方法:
enum Color {
Red, Green, Blue
}
function getRandomColor(): Color {
var key = Math.floor(Math.random() * Object.keys(Color).length / 2);
return Color[key];
}
Color
(题目中要求),实际上它是一个枚举索引而不是颜色名称。TS2322: 类型“number”不能赋值给类型“Color”
。 - jarodsmkObject.keys(Color)
返回6个键0,1,2,Red,Green,BlueRed
,所以我们需要除以二。如果使用字符串枚举,则不会出现此问题,但实现方式会有所不同。 - yoniLaviimport _ from 'lodash';
export function getRandomValueFromEnum<E>(enumeration: { [s: string]: E } | ArrayLike<E>): E {
return _.sample(Object.values(enumeration)) as E;
}
// Get an array of all values in the Colors enum
const colorValues = Object.values(Colors);
// Use arrayElement from faker to pick a random color from the array
const randomColor = faker.helpers.arrayElement(colorValues);
enum Colors {
Red,
blue,
pink,
yellow,
Orange
}
function getRandomColor(): string {
// returns the length
const len = (Object.keys(Colors).length / 2) - 1;
// calculate random number
const item = (Math.floor(Math.random() * len) + 0);
return Colors[item];
}
enum Colors { Red: 100, Blue }
的枚举,这将失败。 - Lazar Ljubenovićconst item = Math.floor(Math.random() * Object.keys(Colors).length);
const i2 = Object.keys(Colors)[item];
return Colors[i2];
- Matt Westlake
Object.values(anEnum).map(n => +n)
替代Object.keys(anEnum).map(n => Number.parseInt(n))
吗?枚举的键都是字符串,而其值是数字和字符串的混合(数字是实际的枚举值,字符串是它的键)。例如,给定enum Bool { FALSE, TRUE }
,Object.keys(Bool)
将返回["0", "1", "FALSE", "TRUE"]
(全部为字符串),但Object.values(Bool)
将返回["FALSE", "TRUE", 0, 1]
(数字和字符串)。 - chharveyenum Stuff {A="A", B="B"}
。编辑:Kabir的答案可行。 - Panossa