50

I use this method Enums in JavaScript? to create enums in our code..

So

var types = {
  "WHITE" : 0,
  "BLACK" : 1
}

Now the issue is when I want create validations anywhere, I have to do this;

model.validate("typesColumn", [ types.WHITE, types.BLACK ]);

Now is there a way I can just simple convert the values in types to an array so that I don't have to list all of the values of the enum?

model.validate("typesColumn", types.ValuesInArray]);

EDIT: I created a very simple enum library to generate simple enums npm --save-dev install simple-enum (https://www.npmjs.com/package/simple-enum)

1
  • This is not enum. This is just an object. Commented Jul 3, 2024 at 5:03

6 Answers 6

124

Simple solution (ES6)

You can use Object.values like this:

var valueArray = Object.values(types);

Online demo (fiddle)

Sign up to request clarification or add additional context in comments.

1 Comment

If the enum is a string, (ex. enum { "Hello", "Goodbye" } then Object.keys(enum) works.
18

I would convert the map into an array and store it as types.all. You can create a method that does it automatically:

function makeEnum(enumObject){
   var all = [];
   for(var key in enumObject){
      all.push(enumObject[key]);
   }
   enumObject.all = all;
}

3 Comments

I think this is the nicest solution.. I can call makeEnum when declaring enums then just be able to call .all
Does this even do what is required? Surely after this all would be and array of property names? like ['WHITE', 'BLACK'] rather than an array of values (which the OP has requested). Also, enum is a reserved word! Why was this accepted?...
I guess the OP took the idea without looking into the exact implementation that is indeed incorrect. I will correct it for other users, thanks for the comment.
10
var types = {
  "WHITE" : 0,
  "BLACK" : 1
}
var typeArray = Object.keys(types).map(function(type) {
    return types[type];
});
//typeArray [0,1]

model.validate("typesColumn", typeArray);

jsFiddle Demo

2 Comments

+1 for Object.keys. Modern JavaScript code for modern environments like node.js!
+1, but I'd rather refactor keys + map to a general function values(obj) and then simply validate("typesColumn", values(types)).
2

You could convert it to an array, or you can just iterate the properties of the object (which is how you would create the array anyway):

for(var i in types){
    var type = types[i];
    //in the first iteration: i = "WHITE", type = 0
    //in the second iteration: i = "BLACK", type = 1
}

Just for completeness, you can create the array with that method as follows:

var arr = [];
for(var i in types){
    var type = types[i];
    arr.push(type);
}
//arr = [0, 1]

to make this reusable you could create a helper function:

function ObjectToValueArray(obj){
    var arr = [];
    for(var i in obj){
        var v = obj[i];
        arr.push(v);
    }
    return arr;
}

Which can be called like so:

model.validate("typesColumn", ObjectToValueArray(types));

2 Comments

I know that I can convert these but since these are used in various places, I'm looking for a one line solution. Something very simple that supports this functionality
Create a helper function and re-use that
1

Juice up (or wrap) .validate such that it will accept types as meaning all members?

var types = {
  "WHITE" : 0,
  "BLACK" : 1,
  "RED"   : 200
}

validate("foo", types.WHITE); // 0
validate("foo", [types.WHITE, types.BLACK]); // 0,1 
validate("foo", types); // 0,1,200

function validate(foo, values) { 
    var arr = [];
    switch (typeof values) {
        case "number":
            arr.push(values);
            break;
        case "object":
            if (values instanceof Array) 
                arr = values;
            else {
                for (var k in values)
                    arr.push(values[k]);
            }
            break;
    }
    alert(arr);
}

Comments

0

ES6 classes for vanila enum creation:

class Colors {
  static get WHITE() { return 0 }
  static get BLACK() { return 1 }

  // generate the list of entries dynamically
  static get entries() {
    return Object.entries(Object.getOwnPropertyDescriptors(this))
      .filter(([key]) => (key === key.toUpperCase()))
      .map(([key, properties]) => ([key, properties.get()]))
  }
}

console.log(Colors.WHITE, Colors.BLACK, Colors.entries)

Some notes about how the above works:

  • The static keyword means that property is bound to the class object itself rather than new instances so they can be called directly
  • The simplest way to do it is actually just to maintain your own static list which can be more performant depending on the size of your enum, but is harder to maintain...
// maintain the list of enum entries as an array
static get entries() { return [
  ['WHITE', this.WHITE],
  ['BLACK', this.BLACK],
] }
  • There are other ways of generating and filtering the list of entries, but I've picked what I feel is the clearest codewise.
  • If you have many enums, it may be worth it to split the entries getter into it's own class that you then extend (great for readability as well) like so:

class Enum {
  static get entries() {
    return Object.entries(Object.getOwnPropertyDescriptors(this))
      .filter(([key]) => (key === key.toUpperCase()))
      .map(([key, properties]) => ([key, properties.get()]))
  }
}

class Colors extends Enum {
  static get WHITE() { return 0 }
  static get BLACK() { return 1 }
}

console.log(Colors.WHITE, Colors.BLACK, Colors.entries)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.