Is there a Javascript data structure that can use a property as an enum index?

Viewed 58
    var Index = {
        X_OFFSET: 1,
        Y_OFFSET: 2,
        Z_OFFSET: 3,
    };

    var options = [
        {name: "X Offset", min:0, max:100, value:0},
        {name: "Y Offset", min:0, max:100, value:0},
        {name: "Z Offset", min:0, max:100, value:0}
    ]
    
    var currentYOffset = options[Index.Y_OFFSET];

[options] is structured so it can be easily saved as an XML file. But to get the value of an option without an index, I'd need to loop through the entire array each time, which just feels inefficient. A simple enum that is identical to the 'name' property would suffice.

EnumMap sounds like it would be appropriate, but doesnt help with XML element name which needs to be a string.

Are there any other data structures appropriate for this, ideally getting rid of the predefined enum entirely.

2 Answers

You can create a mapping of each index to its option ahead of time, allowing for quick lookup later:

var Index = {
    X_OFFSET: 1,
    Y_OFFSET: 2,
    Z_OFFSET: 3,
};

var options = [
    {name: "X Offset", min:0, max:100, value:0},
    {name: "Y Offset", min:0, max:100, value:0},
    {name: "Z Offset", min:0, max:100, value:0}
];

const optionsByName = Object.fromEntries(
  options.map(obj => [Index[obj.name.replaceAll(' ', '_').toUpperCase()], obj])
);


// then later:
var currentYOffset = optionsByName[Index.Y_OFFSET];
console.log(currentYOffset);

This way the iteration only needs to be done once, and if the options array is in the format needed for easy saving, that can be done while still using the optionsByName.

It looks much less messy if you use the same key names in Index as in the options:

var Index = {
    'X Offset': 1,
    'Y Offset': 2,
    'Z Offset': 3,
};

var options = [
    {name: "X Offset", min:0, max:100, value:0},
    {name: "Y Offset", min:0, max:100, value:0},
    {name: "Z Offset", min:0, max:100, value:0}
];

const optionsByName = Object.fromEntries(
  options.map(obj => [Index[obj.name], obj])
);


// then later:
var currentYOffset = optionsByName[Index['Y Offset']];
console.log(currentYOffset);

Or remove the enum entirely:

var options = [
    {name: "X Offset", min:0, max:100, value:0},
    {name: "Y Offset", min:0, max:100, value:0},
    {name: "Z Offset", min:0, max:100, value:0}
];

const optionsByName = Object.fromEntries(
  options.map(obj => [obj.name, obj])
);


// then later:
var currentYOffset = optionsByName['Y Offset'];
console.log(currentYOffset);

If you can't use modern syntax or methods, then:

var options = [
    {name: "X Offset", min:0, max:100, value:0},
    {name: "Y Offset", min:0, max:100, value:0},
    {name: "Z Offset", min:0, max:100, value:0}
];

var optionsByName = {};
for (var i = 0; i < options.length; i++) {
  var obj = options[i];
  optionsByName[obj.name] = obj;
}

// then later:
var currentYOffset = optionsByName['Y Offset'];
console.log(currentYOffset);

#If the enum is pre-defined and name is same as per enum value then you can do like this.

<script>

      var keys = {
        X_OFFSET: 'X Offset',
        Y_OFFSET: 'Y Offset' ,
        Z_OFFSET: 'Z Offset ',
        };


      var options = [
        {name: "X Offset", min:0, max:100, value:0},
        {name: "Y Offset", min:0, max:100, value:0},
        {name: "Z Offset", min:0, max:100, value:0}
    ]
    
    const currentYOffset=options.find((opt)=>opt.name==keys.X_OFFSET);
    console.log(currentYOffset);
    
    
</script>
Related