我有这样定义的枚举:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
但是,我希望将它表示为我们的API中的对象数组/列表,如下所示:
[{id: 1, name: 'Percentage'},
{id: 2, name: 'Numeric Target'},
{id: 3, name: 'Completed Tasks'},
{id: 4, name: 'Average Milestone Progress'},
{id: 5, name: 'Not Measured'}]
是否有简单的本地方法来执行此操作,还是必须构建一个将枚举转换为int和string的函数,并将对象构建为数组?
答案 0 :(得分:17)
枚举是运行时存在的真实对象。所以你可以反转映射做这样的事情:
let value = GoalProgressMeasurements.Not_Measured;
console.log(GoalProgressMeasurements[value]);
// => Not_Measured
基于此,您可以使用以下代码:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
let map: {id: number; name: string}[] = [];
for(var n in GoalProgressMeasurements) {
if (typeof GoalProgressMeasurements[n] === 'number') {
map.push({id: <any>GoalProgressMeasurements[n], name: n});
}
}
console.log(map);
答案 1 :(得分:13)
如果您使用的是ES6
它将为您提供给定枚举的值数组。
enum colors = {
"WHITE" : 0,
"BLACK" : 1
}
const colorValueArray = Object.values(colors);
答案 2 :(得分:12)
一个棘手的问题是TypeScript将“双重”映射发射对象中的枚举,因此可以通过键和值对其进行访问。
enum MyEnum {
Part1 = 0,
Part2 = 1
}
将被发射为
{
Part1: 0,
Part2: 1,
0: 'Part1',
1: 'Part2'
}
因此,您应该在映射之前先过滤对象。因此,@ Diullei的解决方案具有正确的答案。这是我的实现:
// Helper
const StringIsNumber = value => isNaN(Number(value)) === false;
// Turn enum into array
function ToArray(enumme) {
return Object.keys(enumme)
.filter(StringIsNumber)
.map(key => enumme[key]);
}
像这样使用它:
export enum GoalProgressMeasurements {
Percentage,
Numeric_Target,
Completed_Tasks,
Average_Milestone_Progress,
Not_Measured
}
console.log(ToArray(GoalProgressMeasurements));
答案 3 :(得分:12)
我用
Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));
完成任务的简单1行。
只需3个简单步骤即可完成工作
-使用Object.entries
加载键和值的组合。
-过滤掉非数字(因为打字稿会生成用于反向查找的值)。
-然后将其映射到所需的数组对象。
答案 4 :(得分:9)
这将为您提供一系列枚举值:
Value
答案 5 :(得分:8)
简易解决方案。您可以使用以下函数将Enum转换为对象数组。
buildGoalProgressMeasurementsArray(): Object[] {
return Object.keys(GoalProgressMeasurements)
.map(key => ({ id: GoalProgressMeasurements[key], name: key }))
}
如果您需要删除该下划线,我们可以使用正则表达式,如下所示:
buildGoalProgressMeasurementsArray(): Object[] {
return Object.keys(GoalProgressMeasurements)
.map(key => ({ id: GoalProgressMeasurements[key], name: key.replace(/_/g, ' ') }))
}
答案 6 :(得分:4)
首先,我们获得此枚举的键数组。然后,使用map()函数,将数据转换为所需的格式。 id是从键获得的,name是通过相同键从枚举获得的。
const converted = Object.keys(GoalProgressMeasurements).map(key => {
return {
id: GoalProgressMeasurements[key],
name: key,
};
});
答案 7 :(得分:2)
我不喜欢上述任何答案,因为它们都不能正确处理可能是TypeScript枚举中的值的字符串/数字的混合。
以下函数遵循TypeScript枚举的语义,以提供正确的键到值的映射。从那里获取对象数组,键或值都是很简单的。
/**
* Converts the given enum to a map of the keys to the values.
* @param enumeration The enum to convert to a map.
*/
function enumToMap(enumeration: any): Map<string, string | number> {
const map = new Map<string, string | number>();
for (let key in enumeration) {
//TypeScript does not allow enum keys to be numeric
if (!isNaN(Number(key))) continue;
const val = enumeration[key] as string | number;
//TypeScript does not allow enum value to be null or undefined
if (val !== undefined && val !== null)
map.set(key, val);
}
return map;
}
示例用法:
enum Dog {
Rover = 1,
Lassie = "Collie",
Fido = 3,
Cody = "Mutt",
}
let map = enumToMap(Dog); //Map of keys to values
lets objs = Array.from(map.entries()).map(m => ({id: m[1], name: m[0]})); //Objects as asked for in OP
let entries = Array.from(map.entries()); //Array of each entry
let keys = Array.from(map.keys()); //An array of keys
let values = Array.from(map.values()); //An array of values
我还将指出,OP在考虑枚举。枚举中的“键”在技术上位于左侧,而值在右侧。使用TypeScript,您可以根据需要在RHS上重复很多值。
答案 8 :(得分:1)
class EnumHelpers {
static getNamesAndValues<T extends number>(e: any) {
return EnumHelpers.getNames(e).map(n => ({ name: n, value: e[n] as T }));
}
static getNames(e: any) {
return EnumHelpers.getObjValues(e).filter(v => typeof v === 'string') as string[];
}
static getValues<T extends number>(e: any) {
return EnumHelpers.getObjValues(e).filter(v => typeof v === 'number') as T[];
}
static getSelectList<T extends number, U>(e: any, stringConverter: (arg: U) => string) {
const selectList = new Map<T, string>();
this.getValues(e).forEach(val => selectList.set(val as T, stringConverter(val as unknown as U)));
return selectList;
}
static getSelectListAsArray<T extends number, U>(e: any, stringConverter: (arg: U) => string) {
return Array.from(this.getSelectList(e, stringConverter), value => ({ value: value[0] as T, presentation: value[1] }));
}
private static getObjValues(e: any): (number | string)[] {
return Object.keys(e).map(k => e[k]);
}
}
答案 9 :(得分:1)
有一个简单的解决方案,所以当您运行Object.keys(Enum)
时,它将在第一个切片值和第二个键中为您提供一个值和键数组,所以为什么我们不仅仅返回第二个键切片,下面的这段代码对我有用。
enum Enum {
ONE,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN
}
const keys = Object.keys(Enum);
console.log(keys.slice(keys.length / 2));
答案 10 :(得分:1)
TS:
仅适用于短(<10 个元素)枚举
const keys = Object.keys(Enum).filter((el: string) => el.length > 1)
console.log(keys)
答案 11 :(得分:0)
enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
const array = []
for (const [key, value] of Object.entries(GoalProgressMeasurements)) {
if (!Number.isNaN(Number(key))) {
continue;
}
array.push({ id: value, name: key.replace('_', '') });
}
console.log(array);
答案 12 :(得分:0)
您可以通过以下方式做到这一点:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
export class GoalProgressMeasurement {
constructor(public goalProgressMeasurement: GoalProgressMeasurements, public name: string) {
}
}
export var goalProgressMeasurements: { [key: number]: GoalProgressMeasurement } = {
1: new GoalProgressMeasurement(GoalProgressMeasurements.Percentage, "Percentage"),
2: new GoalProgressMeasurement(GoalProgressMeasurements.Numeric_Target, "Numeric Target"),
3: new GoalProgressMeasurement(GoalProgressMeasurements.Completed_Tasks, "Completed Tasks"),
4: new GoalProgressMeasurement(GoalProgressMeasurements.Average_Milestone_Progress, "Average Milestone Progress"),
5: new GoalProgressMeasurement(GoalProgressMeasurements.Not_Measured, "Not Measured"),
}
您可以像这样使用它:
var gpm: GoalProgressMeasurement = goalProgressMeasurements[GoalProgressMeasurements.Percentage];
var gpmName: string = gpm.name;
var myProgressId: number = 1; // the value can come out of drop down selected value or from back-end , so you can imagine the way of using
var gpm2: GoalProgressMeasurement = goalProgressMeasurements[myProgressId];
var gpmName: string = gpm.name;
您可以根据需要使用对象的其他属性扩展GoalProgressMeasurement。我对每个枚举都应该使用这种方法,该枚举应该是一个包含更多值的对象。
答案 13 :(得分:0)
由于具有字符串值的枚举不同于具有数字值的枚举,因此最好从@ user8363解决方案中过滤非数字。
这是从字符串或混合数中获取枚举值的方法:
//Helper
export const StringIsNotNumber = value => isNaN(Number(value)) === true;
// Turn enum into array
export function enumToArray(enumme) {
return Object.keys(enumme)
.filter(StringIsNotNumber)
.map(key => enumme[key]);
}
答案 14 :(得分:0)
我对TypeScript线程感到惊讶,没有人提供支持键入的有效TypeScript函数。这是@ user8363解决方案的变体:
const isStringNumber = (value: string) => isNaN(Number(value)) === false;
function enumToArray<T extends {}>(givenEnum: T) {
return (Object.keys(givenEnum).filter(isStringNumber) as (keyof T)[]).map(
(key) => givenEnum[key]
);
}
答案 15 :(得分:0)
我认为不能保证顺序,否则将Object.entries
结果的后一半切成薄片并从那里映射就足够容易了。
上述答案的唯一(非常小的)问题是
type StandardEnum = { [id: string]: number | string; [nu: number]: string;}
function enumToList<T extends StandardEnum> (enm: T) : { id: number; description: string }[] {
return Object.entries(enm).reduce((accum, kv) => {
if (typeof kv[1] === 'number') {
accum.push({ id: kv[1], description: kv[0] })
}
return accum
}, []) // if enum is huge, perhaps pre-allocate with new Array(entries.length / 2), however then push won't work, so tracking an index would also be required
}
答案 16 :(得分:0)
这是我使用正确键入的简单功能
/**
* Helper to produce an array of enum values.
* @param enumeration Enumeration object.
*/
export function enumToArray<T, G extends keyof T = keyof T>(enumeration: T): T[G][] {
// tslint:disable: comment-format
// enum Colors {
// WHITE = 0,
// BLACK = 1,
// }
// Object.values(Colors) will produce ['WHITE', 'BLACK', 0, 1]
// So, simply slice the second half
const enumValues = Object.values(enumeration);
return enumValues.slice(enumValues.length / 2, enumValues.length) as T[G][];
}
用法示例:
enum Colors {
Red = 1,
Blue = 2,
}
enumToArray(Colors)
答案 17 :(得分:0)
function enumKeys(_enum) {
const entries = Object.entries(_enum).filter(e => !isNaN(Number(e[0])));
if (!entries.length) {
// enum has string values so we can use Object.keys
return Object.keys(_enum);
}
return entries.map(e => e[1]);
}
答案 18 :(得分:0)
另一种使用 ES8 Object.entries
的方法export enum Weeks {
MONDAY = 1,
TUESDAY= 2,
WEDNESDAY = 3,
THURSDAY = 4,
FRIDAY = 5,
SATURDAY=6,
SUNDAY=7,
}
function convertEnumToArray(){
const arrayObjects = []
// Retrieve key and values using Object.entries() method.
for (const [propertyKey, propertyValue] of Object.entries(Weeks)) {
// Ignore keys that are not numbers
if (!Number.isNaN(Number(propertyKey))) {
continue;
}
// Add keys and values to array
arrayObjects.push({ id: propertyValue, name: propertyKey });
}
console.log(arrayObjects);
}
将产生以下内容:
[
{ id: 1, name: 'MONDAY' },
{ id: 2, name: 'TUESDAY' },
{ id: 3, name: 'WEDNESDAY' },
{ id: 4, name: 'THURSDAY' },
{ id: 5, name: 'FRIDAY' },
{ id: 6, name: 'SATURDAY' },
{ id: 7, name: 'SUNDAY' }
]
无耻地从这个blog中偷走