我正在构建这个Builder模式,我想将列表中的一些元素合并在一起。但我想以更清洁的方式做到这一点。这是我到目前为止所提出的有效但我确信有更好的方法来做到这一点。
function FiltersBuilder() {
this.filters = [];
};
FiltersBuilder.prototype.addFilter = function(options) {
var filter = {
'type': 'selector',
'dimension': options.dimension,
'value': options.value
}
this.filters.push(filter);
return this;
}
FiltersBuilder.prototype.addRegexFilter = function(options) {
var filter = {
'type': 'regex',
'dimension': options.dimension,
'pattern': options.value
}
this.filters.push(filter);
return this;
}
FiltersBuilder.prototype.not = function() {
var not = {
'type': 'not'
};
this.filters.push(not);
return this;
}
FiltersBuilder.prototype.getFilters = function() {
var result = [];
this.filters.forEach(function each(filter, index, theFilters) {
if (filter.type === 'not') {
var filterToMerge = theFilters[index + 1];
var mergedFilter = _.merge(filter, {field: filterToMerge});
result.push(mergedFilter);
} else {
if(index > 0) {
notFilter = theFilters[index - 1];
if(notFilter.type === 'not') {
return;
}
}
result.push(filter);
}
});
return result;
}
var filterBuilder = new FiltersBuilder();
filterBuilder.addFilter({
dimension: '_o',
value: 'origin'
});
filterBuilder.not().addRegexFilter({
dimension: 'cTy',
value: 'value'
});
console.log(filterBuilder.getFilters());
如果在添加过滤器之前调用了not
方法,我想将not
过滤器与下一个元素合并,并将该对象添加到result
列表中。但是,如果在添加过滤器之前未调用not
,则不要执行任何操作,只需将过滤器添加到result
列表。
答案 0 :(得分:3)
不是将not
视为要添加到过滤器列表中的过滤器,而是在获得过滤器时进行处理,而是将其视为修饰符 - 标记。在not
对象上维护FiltersBuilder
属性,初始化为false
,对FilterBuilders.not
的调用将切换为not
。在每个过滤器上,还要添加not
属性,该属性由FilterBuilders
上的function FiltersBuilder() {
this.filters = [];
this.not = false;
};
FiltersBuilder.prototype.addFilter = function(options) {
var filter = {
'type': 'selector',
'dimension': options.dimension,
'value': options.value,
not: this.not
}
this.not = false;
this.filters.push(filter);
return this;
}
FiltersBuilder.prototype.addRegexFilter = function(options) {
var filter = {
'type': 'regex',
'dimension': options.dimension,
'pattern': options.value,
not: this.not
}
this.not = false;
this.filters.push(filter);
return this;
}
FiltersBuilder.prototype.not = function() {
this.not = !this.not;
}
FiltersBuilder.prototype.getFilters = function() {
return this.filters;
}
var filterBuilder = new FiltersBuilder();
filterBuilder.addFilter({
dimension: '_o',
value: 'origin'
});
filterBuilder.not().addRegexFilter({
dimension: 'cTy',
value: 'value'
});
console.log(filterBuilder.getFilters());
标志的当前值设置(然后重置)。换句话说:
filterBuilder.not.addFilter
如果您希望能够说not
(not
后没有括号),请将Object.defineProperty(FiltersBuilder.prototype, "not", {
get: function() {
this.not = !this.not;
return this;
}
});
定义为吸气剂,即
{{1}}
答案 1 :(得分:2)
那么,如果我们从右侧迭代它并使用unshift
而不是push
怎么样:
getFilters = function(){
return this.filters.reduceRight(function(results, filter){
if(filter.type === 'not'){
//get filter to 'not'
var notFilter = results[0];
Object.assign(notFilter, filter); //Or _.merge
} else {
results.unshift(filter);
}
return results;
}, []);
}
或者,您可以使用push
代替unshift
,抓取数组的最后一个元素作为否定的过滤器(而不是第一个)并反转结果。
getFilters = function(){
return this.filters.reduceRight(function(results, filter){
if(filter.type === 'not'){
//get filter to 'not'
var notFilter = results[results.length - 1];
Object.assign(notFilter, filter); //Or _.merge
} else {
results.push(filter);
}
return results;
}, []).reverse();
}