web-dev-qa-db-fra.com

TypeScript enum to object array

J'ai un enum défini de cette façon:

export enum GoalProgressMeasurements {
    Percentage = 1,
    Numeric_Target = 2,
    Completed_Tasks = 3,
    Average_Milestone_Progress = 4,
    Not_Measured = 5
}

Cependant, j'aimerais qu'il soit représenté sous forme de tableau/liste d'objets à partir de notre API, comme ci-dessous:

[{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'}]

Y a-t-il un moyen simple et natif de faire cela ou dois-je créer une fonction qui convertit l'énum en un int et une chaîne, et construit les objets dans un tableau?

33
AnimaSola

Les énumérations sont des objets réels qui existent au moment de l'exécution. Vous pouvez donc inverser la cartographie en procédant de la manière suivante:

let value = GoalProgressMeasurements.Not_Measured;
console.log(GoalProgressMeasurements[value]);
// => Not_Measured

Sur cette base, vous pouvez utiliser le code suivant:

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);

Référence: https://www.typescriptlang.org/docs/handbook/enums.html

19
Diullei

Un problème difficile est que TypeScript "double" mapper l'énum dans l'objet émis, afin qu'il soit accessible à la fois par clé et par valeur.

enum MyEnum {
    Part1 = 0,
    Part2 = 1
}

sera émis comme

{
   Part1: 0,
   Part2: 1,
   0: 'Part1',
   1: 'Part2'
}

Vous devez donc d'abord filtrer l'objet avant le mappage. La solution de @Diullei a donc la bonne réponse. Voici ma mise en œuvre:

// 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]);
}

Utilisez-le comme ceci:

export enum GoalProgressMeasurements {
    Percentage,
    Numeric_Target,
    Completed_Tasks,
    Average_Milestone_Progress,
    Not_Measured
}

console.log(ToArray(GoalProgressMeasurements));
17
user8363

Solution facile. Vous pouvez utiliser la fonction suivante pour convertir votre énumération en un tableau d'objets.

 buildGoalProgressMeasurementsArray(): Object[] {

    return Object.keys(GoalProgressMeasurements)
              .map(key => ({ id: GoalProgressMeasurements[key], name: key }))
 }

Si vous aviez besoin de supprimer le trait de soulignement, nous pourrions utiliser regex comme suit:

buildGoalProgressMeasurementsArray(): Object[] {

    return Object.keys(GoalProgressMeasurements)
              .map(key => ({ id: GoalProgressMeasurements[key], name: key.replace(/_/g, ' ') }))
 }
8
Manoj Shrestha
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]);
    }
}
4
Liam Kernighan

Si vous utilisez ES6

Cela vous donnera un tableau de valeurs de l'énumération donnée .

enum colors = {
  "WHITE" : 0,
  "BLACK" : 1
}

const colorValueArray = Object.values(colors);
3
Jai Prak

Vous pouvez le faire de cette façon:

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"),
}

Et vous pouvez l'utiliser comme ceci:

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;

Vous pouvez étendre GoalProgressMeasurement avec des propriétés supplémentaires de l'objet, selon vos besoins. J'utilise cette approche pour chaque énumération qui devrait être un objet contenant plus d'une valeur.

0
Boban Stojanovski