У меня есть перечисление, определенное таким образом:
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, так и в строку, и строит объекты в массив?
javascript
arrays
typescript
enums
casting
AnimaSola
источник
источник
GoalProgressMeasurements[GoalProgressMeasurements.Completed_Tasks]
получить имя перечисления. Не знаю, поможет ли это.Ответы:
Сложность заключается в том, что 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));
источник
enum MyEnum { Part1 = 0, Part2 = 1 }
превращается в,{ Part1: 0, Part2: 1, 0: 'Part1', 1: 'Part2' }
тогда почему, когда выconsole.log(Object.values(MyEnum))
печатаете только 0,1?Object.values(MyEnum)
оценивается до["Part1", "Part2", 0, 1]
console.log(Object.values(MyEnum))
свой компонент. Я использую angular, не уверен, связано ли это. Я не настолько опытен в TypeScriptЕсли вы используете ES6
Это даст вам массив значений данного перечисления .
enum Colors { WHITE = 0, BLACK = 1, BLUE = 3 } const colorValueArray = Object.values(Colors); //[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]
Получится
colorValueArray
вот так[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]
. Все ключи будут в первой половине массива, а все значения - во второй половине.источник
(string | YourEnumType)[]
который вам может не понадобиться в каждом случае.Перечисления - это реальные объекты, существующие во время выполнения. Таким образом, вы можете отменить отображение, сделав что-то вроде этого:
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);
Ссылка: https://www.typescriptlang.org/docs/handbook/enums.html
источник
= 2
до тех пор, пока= 5
- Все, что будет после,= 1
автоматически станет +1.Простое решение. Вы можете использовать следующую функцию для преобразования вашего 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, ' ') })) }
источник
Object.keys(GoalProgressMeasurements) .filter(key => typeof GoalProgressMeasurements[key] === 'number') .map(key => ({ id: GoalProgressMeasurements[key], name: key }))
я использую
Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));
Простая 1 строчка, которая делает свою работу.
Он выполняет свою работу за 3 простых шага
- загружает комбинацию ключей и значений с помощью
Object.entries
.- Отфильтровывает не числа (поскольку машинописный текст генерирует значения для обратного просмотра).
- Затем мы сопоставляем его с объектом массива, который нам нравится.
источник
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]); } }
источник
Это даст вам массив значений перечисления:
Object.values(myEnum);
источник
Сначала мы получаем массив ключей для этого перечисления. Затем с помощью функции map () преобразуем данные в желаемый формат. id получается из ключа, имя получается из enum по тому же ключу.
const converted = Object.keys(GoalProgressMeasurements).map(key => { return { id: GoalProgressMeasurements[key], name: key, }; });
источник
Мне не понравился ни один из приведенных выше ответов, потому что ни один из них не обрабатывает смесь строк / чисел, которые могут быть значениями в перечислениях 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 сколько угодно раз.
источник
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);
источник
Вы можете сделать это следующим образом:
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 дополнительными свойствами объекта по мере необходимости. Я использую этот подход для каждого перечисления, которое должно быть объектом, содержащим более одного значения.
источник
Поскольку перечисления со значениями String отличаются от перечислений с числовыми значениями, лучше отфильтровать nonNumbers из решения @ 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]); }
источник
Я удивлен тем, что в потоке 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] ); }
источник
Существует простое решение, поэтому, когда вы запустите
Object.keys(Enum)
, это даст вам массив значений и ключей, в значениях первого среза и во втором срезе ключи, так почему мы просто не возвращаем второй срез, этот код ниже работает для меня .enum Enum { ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN } const keys = Object.keys(Enum); console.log(keys.slice(keys.length / 2));
источник