Elliot Jalgard
Elliot Jalgard

Reputation: 143

Return a function calling an object's function depending on input parameter

In order to sort a private array of objects containing their own private properties, I need to call their getters in order to retrieve the correct value.

The code below works -- but it goes through the switch every time the value() function is called. This is inefficient and not an elegant solution.

How would you return a function that doesn't need to check the switch on every call?

Side note: Using eval would solve this but I'd rather find another way.

const BY_X = 0;
const BY_Y = 1;
const BY_SUM = 2;

function EntryController() {
  const entries = [/* ... */];

  this.sort = function(sortType, order) {
    const value = (entry) => {
      switch (sortType) {
        case BY_X:
          return entry.getX();
        case BY_Y:
          return entry.getY();
        case BY_SUM:
          return entry.getX() + entry.getY();
        default:
          console.error("Unrecognized sortType: " + sortType);
          return 0;
      };
    };

    entries.sort((a, b) => value(a) > value(b) ^ order);
  }
}

Upvotes: 2

Views: 208

Answers (2)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

You could create a function in switch statement like this.

const value = (() => {
      switch (sortType) {
        case BY_X:
          return entry => entry.getX();
        case BY_Y:
          return entry => entry.getY();
        case BY_SUM:
          return entry => entry.getX() + entry.getY();
        default:
          console.error("Unrecognized sortType: " + sortType);
          return () => 0;
      };
    }());

But I doubt it would significantly affect overall performance. Switch statements are fast even compared to function calls.

Also you could define possible value functions outside of the sort and simply get one by sortType.

const values = {
  [BY_X]: entry => entry.getX(),
  [BY_Y]: entry => entry.getY(),
  ...
}

const unknownSortType = () => 0

and then

this.sort = function(sortType, order) {
  const value = values[sortType] || unknownSortType
  ...
}

Upvotes: 4

bluehipy
bluehipy

Reputation: 2294

It is enough to get the switch out of the value logic since it's done once per sort call.

const BY_X = 0;
const BY_Y = 1;
const BY_SUM = 2;

function EntryController() {
  const entries = [/* ... */];

  this.sort = function(sortType, order) {
  let method;

 switch (sortType) {
    case BY_X:
      method = entries[0].getX; // or from prototype if you know the class
    case BY_Y:
      method = entries[0].getY; // // or from prototype if you know the class
    case BY_SUM:
      method = function(entry){ return entry.getX() + entry.getY(); };
    default:
      console.error("Unrecognized sortType: " + sortType);
      return 0;
  };

const value = (entry) => {
  return method.apply(entry, entry);
};

 entries.sort((a, b) => value(a) > value(b) ^ order);
}
}

Upvotes: 0

Related Questions