개체 배열에 대한 TypeScript 열거
다음과 같이 정의된 열거형이 있습니다.
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와 문자열 모두에 열거를 캐스팅하고 객체를 배열로 빌드하는 함수를 빌드해야 합니까?
ES8을 사용하는 경우
이 경우만 완벽하게 작동합니다.지정된 열거형의 값 배열이 제공됩니다.
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 ]
모든 키는 어레이의 전반부에 있고 모든 값은 후반부에 있습니다.
이런 열거형도 잘 될 거야
enum Operation {
READ,
WRITE,
EXECUTE
}
그러나 이 솔루션은 이와 같은 이기종 Enum에서는 작동하지 않습니다.
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
까다로운 비트는 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은 런타임에 존재하는 실제 개체입니다.따라서 다음과 같은 방법으로 매핑을 되돌릴 수 있습니다.
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
단순히 열거값 배열을 반환합니다.
Object.values(myEnum);
간단한 솔루션다음 함수를 사용하여 Enum을 개체 배열로 변환할 수 있습니다.
buildGoalProgressMeasurementsArray(): Object[] {
return Object.keys(GoalProgressMeasurements)
.map(key => ({ id: GoalProgressMeasurements[key], name: key }))
}
그 밑줄을 떼어낼 필요가 있는 경우는, 다음과 같이 regex 를 사용할 수 있습니다.
buildGoalProgressMeasurementsArray(): Object[] {
return Object.keys(GoalProgressMeasurements)
.map(key => ({ id: GoalProgressMeasurements[key], name: key.replace(/_/g, ' ') }))
}
사용하고 있다
Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));
작업을 수행하는 단순한 1줄입니다.
로 할 수 .
을 - 키와 값의 조합으로 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]);
}
}
polkovnikov.ph 덕분에 대부분의 사용 사례에 적합한 솔루션을 찾을 수 있었습니다.
질문에 대한 유효한 해결책
type Descripted<T> = {
[K in keyof T]: {
readonly id: T[K];
readonly description: string;
}
}[keyof T]
/**
* Helper to produce an array of enum descriptors.
* @param enumeration Enumeration object.
* @param separatorRegex Regex that would catch the separator in your enum key.
*/
export function enumToDescriptedArray<T>(enumeration: T, separatorRegex: RegExp = /_/g): Descripted<T>[] {
return (Object.keys(enumeration) as Array<keyof T>)
.filter(key => isNaN(Number(key)))
.filter(key => typeof enumeration[key] === "number" || typeof enumeration[key] === "string")
.map(key => ({
id: enumeration[key],
description: String(key).replace(separatorRegex, ' '),
}));
}
예:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
console.log(enumToDescriptedArray(GoalProgressMeasurements))
// Produces:
/*
[
{id: 1, description: "Percentage"},
{id: 2, description: "Numeric Target"},
{id: 3, description: "Completed Tasks"},
{id: 4, description: "Average Milestone Progress"},
{id: 5, description: "Not Measured"}
]
*/
또한 열거형 객체를 가지고 있는 사용 가능한 값의 배열에 매핑하기 위해 사용하는 유용한 util 함수도 있습니다.
더 매퍼
type NonFunctional<T> = T extends Function ? never : T;
/**
* Helper to produce an array of enum values.
* @param enumeration Enumeration object.
*/
export function enumToArray<T>(enumeration: T): NonFunctional<T[keyof T]>[] {
return Object.keys(enumeration)
.filter(key => isNaN(Number(key)))
.map(key => enumeration[key])
.filter(val => typeof val === "number" || typeof val === "string");
}
업무용 유스케이스
- 숫자 열거
enum Colors1 {
WHITE = 0,
BLACK = 1
}
console.log(Object.values(Colors1)); // ['WHITE', 'BLACK', 0, 1]
console.log(enumToArray(Colors1)); // [0, 1]
- 문자열 열거
enum Colors2 {
WHITE = "white",
BLACK = "black"
}
console.log(Object.values(Colors2)); // ['white', 'black']
console.log(enumToArray(Colors2)); // ['white', 'black']
- 이종 열거
enum Colors4 {
WHITE = "white",
BLACK = 0
}
console.log(Object.values(Colors4)); // ["BLACK", "white", 0]
console.log(enumToArray(Colors4)); // ["white", 0]
- Enum이 내보낸 함수가 있는 네임스페이스와 병합됨
enum Colors3 {
WHITE = "white",
BLACK = "black"
}
namespace Colors3 {
export function fun() {}
}
console.log(Object.values(Colors3)); // ['white', 'black', Function]
console.log(enumToArray(Colors3)); // ['white', 'black']
TypeScript enum에서 값이 될 수 있는 문자열/숫자의 조합을 올바르게 처리하는 답변이 없기 때문에 위의 답변 중 어느 것도 마음에 들지 않았습니다.
다음 함수는 TypeScript enums의 의미론에 따라 키에 대한 적절한 Map to value를 제공합니다.여기서 객체 배열, 키 또는 값만 가져오는 것은 매우 간단합니다.
/**
* 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
let 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 값을 반복할 수 있습니다.
한 줄만:
Object.entries(GoalProgressMeasurements).map(([key, value]) => ({id: key, value: value}))
어레이 내부의 열거값을 가져오는 예:
export enum DocumentationTypeEnum {
GDPR = 'GDPR',
HELP = 'HELP',
OTHER = 'OTHER',
FOOTER = 'FOOTER'
}
const keys = Object.keys(DocumentationTypeEnum);
console.log(keys); // Output : ["GDPR", "HELP", "OTHER", "FOOTER"]
먼저 이 열거형의 키 배열을 가져옵니다.그런 다음 지도() 기능을 사용하여 데이터를 원하는 형식으로 변환합니다.id는 키에서 취득하고, name은 같은 키로 enum에서 취득합니다.
const converted = Object.keys(GoalProgressMeasurements).map(key => {
return {
id: GoalProgressMeasurements[key],
name: key,
};
});
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' }
]
이 블로그에서 뻔뻔하게 도둑맞았다
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);
간단한 해결책이 있습니다. 그래서 당신이 도망칠 때Object.keys(Enum)
첫 번째 슬라이스 값 및 두 번째 슬라이스 키에서 값 배열과 키를 얻을 수 있으므로 두 번째 슬라이스만 반환하지 않는 이유는 아래 코드가 좋습니다.
enum Enum {
ONE,
TWO,
THREE,
FOUR,
FIVE,
SIX,
SEVEN
}
const keys = Object.keys(Enum);
console.log(keys.slice(keys.length / 2));
저는 몇 달 만에 활자본을 알았고, 아래의 솔루션이 효과가 있었습니다.누군가에게 도움이 되길 바랍니다.
export enum ScheduleType {
Basic = <any>'B',
Consolidated = <any>'C',
}
scheduleTypes = Object.keys(ScheduleType)
.filter((k, i) => i % 2)
.map((key: any) => {
return {
systemValue: key,
displayValue: ScheduleType[key],
};
});
다음 결과를 얻었습니다. [{displayValue: "Basic", systemValue: "B", {displayValue: "Consolidated", systemValue: "C"}]
열거형 엔트리의 리스트가 필요한 경우 TS Enums를 사용하지 않도록 하겠습니다.
실행 시 Enum은 개체로 구현되지만 다음 경우에만 예상대로 작동합니다.
enum X {
Z = 'z',
F = 'f'
};
console.log(Object.values(X))
console.log(Object.keys(X))
>>>
[LOG]: ["z", "f"]
[LOG]: ["Z", "F"]
이 경우 트랩과 함께 동작합니다(TS를 통해 수치로 값에 액세스할 수 있습니다).
enum X {
Z,
F
};
console.log(Object.values(X))
console.log(Object.keys(X))
>>>
[LOG]: ["Z", "F", 0, 1]
[LOG]: ["0", "1", "Z", "F"]
따라서 Enum을 루프하기 위해 쓰는 함수는 Enum 정의에 따라 작동/실패합니다.그게 뭐냐면...좋지 않습니다.
결론:Enum은 개체로 사용하도록 설계되지 않았습니다.사용하다const
대신enum
키 및 값 수집에 액세스해야 하는 경우:
const Enumed = {
X: 1,
Y: 2
}
Typescript는 오브젝트 키의 존재를 제어하며 사용자는 다음을 수행할 수 있습니다.Object.keys
, 등, 안전하고 일관성 있는 방법으로.
export function enumKeys(E: any): string[] {
return Object.keys(E).filter(k => isNaN(Number(k)));
}
export function enumValues(E: any): string[] | number[] {
return enumKeys(E).map(k => E[k as any]);
}
양쪽에서 동작:
enum TestA {
RED = "red",
BLUE = "blue"
}
enum TestB {
ONE = 1,
TWO = 2
}
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]);
}
다음과 같이 할 수 있습니다.
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를 확장할 수 있습니다.값을 더 많이 포함하는 개체여야 하는 모든 열거에 대해 이 방법을 사용합니다.
Strings 값을 가진 Enum과 숫자 값을 가진 Enum은 다르므로 @user8363 솔루션에서 nonNumbers를 필터링하는 것이 좋습니다.
다음은 enum, 즉 혼합 문자열 수에서 값을 가져오는 방법을 보여 줍니다.
//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.entries
결과 및 맵이 표시됩니다.
위의 답변에 관한 유일한 (매우 사소한) 문제는 다음과 같은 문제가 있습니다.
- 문자열과 숫자 사이에 불필요한 변환이 많이 있습니다.
- 단일 반복이 깨끗하고 효과적일 때 엔트리가 2회 반복됩니다.
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
}
탐:
쇼트(<10 요소) 열거형에서만 동작합니다.
const keys = Object.keys(Enum).filter((el: string) => el.length > 1)
console.log(keys)
- Object.keys()는 ['0', '1', '2', 'enumElement1', 'enumElement2', enumElement3]의 배열을 반환합니다.
- filter()는 모든 요소를 가져와서 (문자열 때문에) 길이를 체크하고 결과 배열에서 모든 숫자를 제외합니다.
문에 기반한 이 메서드: enum 키는 숫자일 수 없습니다.
export const isNumeric = (num?: Value | null): num is number => {
if (num === undefined || num === null) {
return false;
}
const number = +num;
if (number - number !== 0) {
// Discard Infinity and NaN
return false;
}
if (number === num) {
return true;
}
if (typeof num === 'string') {
return !(number === 0 && num.trim() === '');
}
return false;
};
enum En {
ewq1 = 1,
we2 = 'ss',
sad = 'sad',
}
type TEnum = {
[id: string]: number | string;
}
export const getEnumValues = <T extends TEnum>(enumerable: T) =>
Object.keys(enumerable)
.filter((x) => !isNumeric(x))
.map((key) => enumerable[key] as T[keyof T])
console.log(getEnumValues(En)) // [1, "ss", "sad"]
또 다른 방법은
export const GoalNames = {
[GoalProgressMeasurements.Percentage] = 'Percentage',
[GoalProgressMeasurements.Numeric_Target] = 'Numeric Target',
[GoalProgressMeasurements.Completed_Tasks] = 'Completed Tasks',
[GoalProgressMeasurements.Average_Milestone_Progress] = 'Average Milestone Progress',
[GoalProgressMeasurements.Not_Measured] = 'Not Measured'
}
문의처:
const name = GoalNames[goalEnumVal];
나는 이 방법으로 해결했다.
const listKeys = Object.keys(TripStatus); //TripStatus is enum type
const numOfItem = listKeys.length/2;
for(let i=0; i<numOfItem; i++){
this.listStatus.push({
id: listKeys[i],
name: listKeys[numOfItem+i]
})
}
enum 변수는 다음과 같습니다.
enum EnumName {
A = 1,
B = 2
};
다음으로 리스트는 다음과 같습니다.
const list = Object.keys(Enum)
.filter((value => isNaN(Number(value)) === false))
.map(key => ({ id: key, value: Enum[key] }));
목록의 값은 다음과 같습니다.
list = [
{ id:1 , value: A },
{ id:2 , value: B },
];
this worked for me :
export enum FeedBackType {
FEEDBACK1= 'FEEDBACK1',
FEEDBACK2= 'FEEDBACK2',
FEEDBACK3= 'FEEDBACK3',
}
-----------------------------------------------------------------
export function getTypeFeedBackList() {
let feedbackList: FeedBackType[] = [];
Object.keys(FeedBackType).map((key) => {
let strEnum = key as unknown as FeedBackType;
feedbackList.push(strEnum);
});
return feedbackList;
}
----------------------------------------------------------------
declare this :
public feedbackList: FeedBackType[] = [];
and after call your function in :
ngOnInit(): void {
this.feedbackList = getTypeFeedBackList();
console.log(this.feedbackList);
}
Happy coding ;)
이런 식으로 해결했어요다음과 같은 열거형이 있다고 가정합니다.
export enum UnitEnum {
GRAM = 'gm',
KILOGRAM = 'kg',
LITRE = 'lt',
CENTIMETER = 'cm',
INCH = 'in',
METER = 'mt',
KILOMETER = 'km',
}
그리고 이런 수업도 있고
export interface Unit {
Name: string;
Symbol: string;
}
그런 다음 다음과 같은 함수를 만들어 특정 유형의 객체에 이기종 Enum을 매핑할 수 있습니다.
export function getDefaultUnits() {
const myUnits = Object.entries(UnitEnum).map(x => {
return { Name: x[0], Symbol: x[1] } as Unit
})
console.log(myUnits);
return myUnits;
}
언급URL : https://stackoverflow.com/questions/43100718/typescript-enum-to-object-array
'programing' 카테고리의 다른 글
시작 시 MongoDB 컨테이너를 위한 DB를 만드는 방법은 무엇입니까? (0) | 2023.03.14 |
---|---|
WooCommerce 체크아웃 필드 값 제거 (0) | 2023.03.14 |
네트워크 프록시 뒤의 스프링 부트 (0) | 2023.03.14 |
Angular 1.6에서 처리되지 않은 거부일 수 있음 (0) | 2023.03.14 |
React 및 TypeScript - Axios 응답 유형 (0) | 2023.03.08 |