Как я могу разорвать цепочку пользовательских методов, все еще возвращая значение?
Я выполняю замену в поисковой переменной, превращая известные группы в имена групп.
Мне кажется, что на каждом шаге я могу выполнить сопоставление регулярных выражений и посмотреть, есть ли еще два или более членов группы в поисковом запросе, и если нет, прервать цепочку. Это функция, которую я использую регулярно, и она отвечает за выход из процесса, если не осталось совпадений.
Моя фактическая цепочка замен - 15 длинных, если я могу выйти из этого на первом или втором, это кажется уместным.
Итак, я думал, что напишу что-то вроде этого
String.prototype.abortreplace = function (m,r) {
var toreturn;
if (this.match(/\b\w\b/g).length > 0) {
toreturn = this.replace(m,r);
} else {
return;
}
return toreturn;
}
tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = tx.abortreplace(/a,b,c/g,"first three letters").abortreplace(/d,e,f/g,"second three letters").abortreplace(/g,h,i/g,"third three letters").abortreplace(/j,k,l/g,"fourth three letters").abortreplace(/m,n,o/g,"fifth three letters").abortreplace(/p,q,r/g,"sixth three letters");
alert(tx2);
Это работает с этой конкретной строкой из-за p в конце строки и потому, что у меня есть length > 0
, На практике длина будет length > 2
, В этом случае он возвращает undefined
и ломается. Мне интересно, как я могу вернуть строку и все же разорвать цепь. (Я тоже пробовал return false
который возвращает false, а не undefined).
String.prototype.abortreplace = function (m,r) {
var toreturn;
if (this.match(/\b\w\b/g).length > 2) {
toreturn = this.replace(m,r);
} else {
return;
}
return toreturn;
}
tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = tx.abortreplace(/a,b,c/g,"first three letters").abortreplace(/d,e,f/g,"second three letters").abortreplace(/g,h,i/g,"third three letters").abortreplace(/j,k,l/g,"fourth three letters").abortreplace(/m,n,o/g,"fifth three letters").abortreplace(/p,q,r/g,"sixth three letters");
alert(tx2);
Четкий обходной путь заключается в том, чтобы просто return this
когда условие не совпадает, но, конечно, это не прерывает цепочку, оно просто сводит на нет каждый последующий шаг.
Я также знаю, что я мог бы так примерно так:
var groups = ["a,b,c","d,e,f"]
var gnames = ["first three letters","second three letters"]
function chainreplace(query,step) {
if (this.match(/\b\w\b/g).length > 0) {
query = query.replace(groups[step],gnames[step]);
if (step < groups.length) {
query = chainreplace(query,step+1);
}
return query;
}
}
chainreplace("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p",1);
Но я предпочитаю метод цепочки, если это возможно, проще для повторного использования (аналогично, но не идентично), без создания большего количества массивов объектов
1 ответ
Вместо того, чтобы ставить свои собственные методы на String
Прототип (тьфу), вы можете придумать свою собственную структуру данных, чтобы делать то, что вы хотите.
Идея ниже состоит в том, что есть один тип объекта, который выполняет необходимую обработку и возвращает цепочечные объекты, и когда придет время, он может вернуть другой тип с тем же интерфейсом, который закорачивает последующие вызовы цепочки:
var replacer = (function() {
function fixedReplacer(str) {
var r = {
abortreplace: function() {
// this abortreplace just returns the object it was called on
return r;
},
toString: function() {
return str;
}
};
return r;
}
function replacer(str) {
return {
abortreplace: function(m, r) {
return (str.match(/\b\w\b/g)||[]).length > 2
? replacer(str.replace(m, r))
: fixedReplacer(str);
},
toString: function() {
return str;
}
};
}
return replacer;
})();
tx = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p";
tx2 = replacer(tx)
.abortreplace(/a,b,c/g, "first three letters")
.abortreplace(/d,e,f/g, "second three letters")
.abortreplace(/g,h,i/g, "third three letters")
.abortreplace(/j,k,l/g, "fourth three letters")
.abortreplace(/m,n,o/g, "fifth three letters")
.abortreplace(/p,q,r/g, "sixth three letters")
.toString();
console.log(tx2);
Конечно, это не препятствует выполнению всех 15 вызовов методов (как указали Феликс и Берги, это невозможно без исключения), но может значительно сократить объем выполняемых вычислений.