Конструктор принимает (1) список строк;(2) массив ул;(3) карта - PullRequest
0 голосов
/ 12 октября 2019

Я хотел бы расширить конструктор таким образом, чтобы две строки с уровнем и цветом можно было раскомментировать. То есть можно сгенерировать перечисление с картой и перечисление со списком (эта секунда имеет низкий приоритет).

Я могу отказаться от рабочего (незафиксированного) варианта и принять только массив, а затем проверить, еслиэлементы - это строки или объекты, но это решение не будет таким нишевым, как то, которое я ищу (пока оно существует ...).

class Enum {
  constructor (...values) {
    this.values = values;
    // this.map = None; 
  }

  check (value) {
    //if (this.map) {
    //  return this.map.keys().indexOf(value) !== -1;
    // } else {
      return this.values.indexOf(value) !== -1;
    // }

  }
}

const enums = {
  Size: new Enum('small', 'big', 'huge'),
  // Level: new Enum({'1': {txt: 'h1'}, '2': {txt: 'h2'}, '3': {txt: 'h3'}}),
  // Color: new Enum(['small', 'big', 'huge']),
};

export default enums;

Ответы [ 3 ]

2 голосов
/ 12 октября 2019

«Полиморфные» конструкторы в основном плохая идея, потому что их сложно программировать (как вы уже знаете), а также сложнее отследить в коде. Вместо этого я бы предложил использовать специализированные фабричные функции для каждого возможного типа аргумента. Пример:

class Enum {
    constructor(pairs) {
        for (let [name, val] of pairs)
            this[name] = val;
    }

    static from(names) {
        return new this([...names.entries()].map(([k, v]) => [v, k]));
    }

    static of(...names) {
        return this.from(names);
    }


    static fromObject(obj) {
        return new this(Object.entries(obj));
    }
}


const enums = {
    Size: Enum.of('small', 'big', 'huge'),
    Level: Enum.fromObject({'first': {txt: 'h1'}, 'second': {txt: 'h2'}, 'third': {txt: 'h3'}}),
    Color: Enum.from(['red', 'orange', 'blue']),
    Flags: new Enum([['read', 1], ['write', 2], ['execute', 4]])
};

console.log(enums.Size.huge)
console.log(enums.Color.orange)
console.log(enums.Level.third)
console.log(enums.Flags.execute)
1 голос
/ 12 октября 2019

Вы можете проверить, является ли values[0] массивом. Затем проверьте, является ли values[0] объектом. Не уверен, какие значения должны быть для этого сценария. Оставшийся сценарий предназначен для Size. В этом случае напрямую назначьте this.values = values

class Enum {

  constructor(...values) {
    if (Array.isArray(values[0]))
      this.values = values[0]
      
    else if (typeof values[0] === 'object')
      this.values = Object.keys(values[0]) // not sure
      
    else this.values = values;
  }

  check(value) {
    return this.values.indexOf(value) !== -1;
  }
}

const enums = {
    Size: new Enum('small', 'big', 'huge'),
    Level: new Enum({'1': {txt: 'h1'}, '2': {txt: 'h2'}, '3': {txt: 'h3'}}),
    Color: new Enum(['small', 'big', 'huge']),
};

console.log(enums)
0 голосов
/ 12 октября 2019

Вот решение с помощью @Bergi.

class Enum {
  constructor (...keys) {
    this.keys = null;
    this.map = null;
    if (typeof keys[0] === 'string') {
      this.keys = keys;
    } else if (Array.isArray(keys[0])) {
      this.keys = keys[0];
    } else {
      this.map = keys[0];
    }
  }

  check (key) {
    if (this.keys != null) {
      return this.keys.indexOf(key) !== -1;
    } else if (this.map != null) {
      return key in this.map;
    } else {
      return null;
    }
  }

  value (key) {
    if (this.keys) {
      return (this.keys.indexOf(key) !== -1 ? key : null);
    } else if (this.map) {
      return (key in this.map ? this.map[key] : null);
    } else {
      return null;
    }
  }
}

const enums = {
  Size: new Enum('small', 'big', 'huge'),
  Color: new Enum(['red', 'green', 'blue']),
  Level: new Enum({
    '1': {
      text: 'h1',
    },
    '2': {
      text: 'h2',
    },
    '3': {
      text: 'h3',
    },
  }),
};

console.log(enums.Size.check('big'));
console.log(enums.Size.value('big'));
console.log(enums.Size.check('aaa'));
console.log(enums.Size.value('aaa'));
console.log(enums.Color.check('green'));
console.log(enums.Color.value('green'));
console.log(enums.Level.check('1'));
console.log(enums.Level.value('1').text);
console.log(enums.Level.check('8'));
console.log(enums.Level.value('8'));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...