Ich habe eine Aufzählung wie folgt definiert:
export enum GoalProgressMeasurements {
Percentage = 1,
Numeric_Target = 2,
Completed_Tasks = 3,
Average_Milestone_Progress = 4,
Not_Measured = 5
}
Ich möchte jedoch, dass es wie folgt als Objektarray / -liste aus unserer API dargestellt wird:
[{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'}]
Gibt es eine einfache und native Möglichkeit, dies zu tun, oder muss ich eine Funktion erstellen, die die Aufzählung sowohl in ein int als auch in einen String umwandelt, und die Objekte in ein Array einbauen?
javascript
arrays
typescript
enums
casting
AnimaSola
quelle
quelle
GoalProgressMeasurements[GoalProgressMeasurements.Completed_Tasks]
folgt umkehren: um den Namen der Aufzählung zu erhalten. Ich weiß nicht, ob das hilft.Antworten:
Ein kniffliges Problem ist, dass TypeScript die Aufzählung im ausgegebenen Objekt "doppelt" abbildet, sodass sowohl über den Schlüssel als auch über den Wert darauf zugegriffen werden kann.
enum MyEnum { Part1 = 0, Part2 = 1 }
wird ausgegeben als
{ Part1: 0, Part2: 1, 0: 'Part1', 1: 'Part2' }
Sie sollten das Objekt also zuerst filtern, bevor Sie es zuordnen. Die Lösung von @Diullei hat also die richtige Antwort. Hier ist meine Implementierung:
// 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]); }
Verwenden Sie es so:
export enum GoalProgressMeasurements { Percentage, Numeric_Target, Completed_Tasks, Average_Milestone_Progress, Not_Measured } console.log(ToArray(GoalProgressMeasurements));
quelle
enum MyEnum { Part1 = 0, Part2 = 1 }
wird{ Part1: 0, Part2: 1, 0: 'Part1', 1: 'Part2' }
dann, warum, wenn Sieconsole.log(Object.values(MyEnum))
nur 0,1 drucken?Object.values(MyEnum)
bewertet zu["Part1", "Part2", 0, 1]
console.log(Object.values(MyEnum))
in meiner Komponente gedruckt . Ich benutze eckig, nicht sicher, ob das verwandt ist. Ich bin nicht so erfahren in TypeScriptWenn Sie ES6 verwenden
Sie erhalten ein Wertearray der angegebenen Aufzählung .
enum Colors { WHITE = 0, BLACK = 1, BLUE = 3 } const colorValueArray = Object.values(Colors); //[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]
Sie erhalten
colorValueArray
wie diese[ 'WHITE', 'BLACK', 'BLUE', 0, 1, 3 ]
. Alle Schlüssel befinden sich in der ersten Hälfte des Arrays und alle Werte in der zweiten Hälfte.quelle
(string | YourEnumType)[]
der nicht in jedem Fall gewünscht wird.Aufzählungen sind reale Objekte, die zur Laufzeit vorhanden sind. Sie können das Mapping also wie folgt umkehren:
let value = GoalProgressMeasurements.Not_Measured; console.log(GoalProgressMeasurements[value]); // => Not_Measured
Basierend darauf können Sie den folgenden Code verwenden:
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);
Referenz: https://www.typescriptlang.org/docs/handbook/enums.html
quelle
= 2
erst schreiben, wenn= 5
- Alles danach= 1
automatisch +1 ist.Einfache Lösung. Mit der folgenden Funktion können Sie Ihre Aufzählung in ein Array von Objekten konvertieren.
buildGoalProgressMeasurementsArray(): Object[] { return Object.keys(GoalProgressMeasurements) .map(key => ({ id: GoalProgressMeasurements[key], name: key })) }
Wenn Sie diesen Unterstrich entfernen müssen, können Sie Regex wie folgt verwenden:
buildGoalProgressMeasurementsArray(): Object[] { return Object.keys(GoalProgressMeasurements) .map(key => ({ id: GoalProgressMeasurements[key], name: key.replace(/_/g, ' ') })) }
quelle
Object.keys(GoalProgressMeasurements) .filter(key => typeof GoalProgressMeasurements[key] === 'number') .map(key => ({ id: GoalProgressMeasurements[key], name: key }))
ich benutze
Object.entries(GoalProgressMeasurement).filter(e => !isNaN(e[0]as any)).map(e => ({ name: e[1], id: e[0] }));
Eine einfache 1 Zeile, die den Job erledigt.
Es erledigt die Arbeit in 3 einfachen Schritten
- Lädt die Kombination von Schlüsseln und Werten mit
Object.entries
.- Filtert die Nicht-Zahlen heraus (da Typoskript die Werte für die umgekehrte Suche generiert).
- Dann ordnen wir es dem Array-Objekt zu, das wir mögen.
quelle
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]); } }
quelle
Dadurch erhalten Sie eine Reihe von Aufzählungswerten:
Object.values(myEnum);
quelle
Zuerst erhalten wir eine Reihe von Schlüsseln für diese Aufzählung. Anschließend konvertieren wir mit der Funktion map () die Daten in das gewünschte Format. id wird vom Schlüssel erhalten, name wird von enum durch denselben Schlüssel erhalten.
const converted = Object.keys(GoalProgressMeasurements).map(key => { return { id: GoalProgressMeasurements[key], name: key, }; });
quelle
Ich mochte keine der obigen Antworten, weil keine von ihnen die Mischung von Zeichenfolgen / Zahlen, die Werte in TypeScript-Aufzählungen sein können, korrekt handhabt.
Die folgende Funktion folgt der Semantik von TypeScript-Enums, um eine korrekte Zuordnung von Schlüsseln zu Werten zu erhalten. Von dort aus ist es trivial, ein Array von Objekten oder nur die Schlüssel oder nur die Werte zu erhalten.
/** * 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; }
Anwendungsbeispiel:
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
Ich werde auch darauf hinweisen, dass das OP rückwärts an Aufzählungen denkt. Der "Schlüssel" in der Aufzählung befindet sich technisch auf der linken Seite und der Wert befindet sich auf der rechten Seite. Mit TypeScript können Sie die Werte auf der rechten Seite so oft wiederholen, wie Sie möchten.
quelle
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);
quelle
Sie können dies folgendermaßen tun:
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"), }
Und Sie können es so verwenden:
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;
Sie können die GoalProgressMeasurement nach Bedarf um zusätzliche Eigenschaften des Objekts erweitern. Ich verwende diesen Ansatz für jede Aufzählung, die ein Objekt sein sollte, das mehr als einen Wert enthält.
quelle
Da sich Aufzählungen mit Strings-Werten von denen mit Zahlenwerten unterscheiden, ist es besser, Nicht-Zahlen aus der @ user8363-Lösung zu filtern.
Hier ist, wie Sie Werte aus enum entweder Zeichenfolgen, Anzahl von gemischt erhalten können:
//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]); }
quelle
Ich bin überrascht, dass in einem TypeScript-Thread niemand eine gültige TypeScript-Funktion mit unterstützter Eingabe angegeben hat. Hier ist eine Variation der @ user8363-Lösung:
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] ); }
quelle
Es gibt eine einfache Lösung. Wenn Sie also diese ausführen
Object.keys(Enum)
, erhalten Sie ein Array von Werten und Schlüsseln in den Werten des ersten Slice und im zweiten Schlüssel. Warum wir also nicht nur das zweite Slice zurückgeben, funktioniert dieser Code unten für mich .enum Enum { ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN } const keys = Object.keys(Enum); console.log(keys.slice(keys.length / 2));
quelle