Сортировка массива в JavaScript с помощью регулярных выражений


Я с помощью jsom в SharePoint 2013. Мой переменной this.templates содержит коллекцию шаблонов с различными именами. Единственный способ для перебора этой коллекции с помощью перечислителя. Я могу только получить имя каждого шаблона с помощью get_title().

Я хочу получить шаблоны, имена которых соблюдать следующие правила:

  • Он содержит "espace_projet"
  • Он содержит буквы "V", за которой следует любое количество раз

Затем, из шаблонов у меня есть, я хочу, чтобы получить один с наибольшим значением, что после "Фау".

Я не привык к JavaScript, этот код прекрасно работает, но чувствует, как Overkill. Как я могу сделать его короче/более читаемым?

ApplyTemplate()
{
    var highestVersion = {number: -1, template: null};
    var templateEnum = this.templates.getEnumerator();

    while(templateEnum.moveNext())
    {
        //Gets the element name in my collection
        var templateName = templateEnum.get_current().get_title();
        if(templateName.includes('espace_projet'))
        {
            var version = templateName.match('v[0-9]+|v_[0-9]+');
            if(version){
                var versionNumber = version[0].match('[0-9]+');
                if(versionNumber[0] > highestVersion.number)
                    highestVersion = {number: versionNumber[0], template: templateEnum.get_current()};
            }
        }
    }

    return highestVersion;
}


Комментарии
2 ответа

Вы его практически идеальным в вашем вопросе. С небольшого улучшения можно уменьшить память и загрузка процессора.


  1. Не создавать новый объект каждый раз, когда вы найти следующую версию. Задайте свойства существующего объекта на новый высший.

  2. Только звонить templateEnum.get_current() один раз, вы не должны называть его снова, когда вы найдете самый высокий вариант

  3. Не проходят строк String.match это требует дополнительных издержек, чтобы преобразовать строку в регулярное выражение

  4. Не тестируют одно и то же дважды. .match('v[0-9]+|v_[0-9]+') и .match('[0-9]+') может быть сделано в один шаг.

И какой стиль очков


  1. Функция вызывается ApplyTemplate (не должно быть оприходовано) хотя мне кажется, чтобы найти высокий шаблон. Может, лучше имя?

  2. Функция о шаблонах, нужно ли добавить шаблон templateEnum, templateName хороший именования использует контекст, чтобы сделать вывод. Держать короткие имена, не добавляя избыточной и прогнозные данные.

Таким образом, ваша функция будет

highestVersionTemplate() {
const highest = { number: -1 };
const enumer = this.templates.getEnumerator();
while (enumer.moveNext()) {
const current = enumer.get_current();
const title = current.get_title();
if (title.includes("espace_projet")) {
const ver = title.match(/v_?([0-9]+)/);
if (ver && ver[1] > highest.number) {
highest.number = Number(ver[1]);
highest.template = current;
}
}
}
return highest;
},

1
ответ дан 16 марта 2018 в 11:03 Источник Поделиться

Рекомендации по содержанию


  • Использовать const где это возможно, в противном случае let. Избежать var.

  • Матч номер версии только один раз (см. код ниже) и использовать ? оператор для сохранения избыточности: v_?[0-9].
    (Последнее может быть спорным, я лично считаю, что обе версии легко читать.)

Ваш код будет короче и гораздо легче рассуждать, если он был более функциональным.
Однако, как JS не хватает некоторых функциональных понятий других языков принять на веру (понимание массив, мин/макс в массиве по основным функции), это потребует вспомогательных функций, будучи новым, но некогда над головой. Вы используете стороннюю библиотеку, как Лодашь случайно? Тогда у вас уже есть много функциональных полифиллы.

Какие методы не Enumerator вы используете SharePoint поддерживают не только итерационный запрос интерфейс moveNext(), get_current()? Если нет встроенной поддержки, я предлагаю написать функцию генератора:

function *getTemplateIterator(templates) {
const templateEnum = templates.getEnumerator();
while (templateEnum.moveNext()) {
yield templateEnum.get_current();
}
}

function ApplyTemplate() {
return [...getTemplateIterator(this.templates)]
.filter(template => template.get_title().includes('espace_projet'))
.map(template => {
const version = /v_?([0-9]+)/.match(template.get_title());
return {
version: (version !== null) ? parseInt(version[1], 10) : -1
template: template
};
})
.reduce((highestVersionedTemplate, template) =>
(template.version > highestVersionedTemplate) ? template : highestVersionedTemplate,
{ version: -1, template: null }
);
// In contrast with an array max/min function suporting a key extracting function
// (e.g. like in Python: https://docs.python.org/3.8/library/functions.html#max)
previousChainOfFunctions.maxOrDefault(template => template.version, { version: -1, template: null });
}

Стилистических соображений


  • Ваши имена переменных не требуют пояснений и последовательно написано, это прекрасно!

  • Использование последовательной скобы в блоках (function, ifмногие больше), например function { или function[newline]{но не смешивайте оба.

  • Всегда используйте фигурные скобки вокруг if, else, for, while.

1
ответ дан 16 марта 2018 в 05:03 Источник Поделиться