[英]How to simplify this filter written in underscore.js?
給定是一個具有一系列條件的對象:
var conditions = {
even: function (i) { return i % 2 == 0; },
greatherThan: function (i) { return i > 10; },
inValidRange: function (i) {
return i > 20 && i < 100;
}
};
以及從0到39的范圍內的數組編號: var numbers = _.range(0, 40);
。
我想按各種條件過濾numbers
。 我使用underscore.js來做到這一點:
var result = _.filter(numbers, function(current) {
return _.all(_.values(conditions), function(f) {
return f(current);
});
});
// returns [ 22, 24, 26, 28, 30, 32, 34, 36, 38 ]
它工作正常,但不幸的是,上面的代碼看起來很奇怪,而且非常令人困惑。
如何簡化此代碼以使其更易讀和易懂?
這個輔助函數可能很有用:
_.mixin({
invokeWith: function() {
var args = arguments;
return function(fn) {
return fn.apply(null, args);
};
}
});
如果你的conditions
是一個陣列,那也會更好。 您可以使用一組命名函數:
var conditions = [
function even(i) { return i % 2 == 0; },
function greaterThan(i) { return i > 10; },
function inValidRange(i) { return i > settings.validRange.from && i < settings.validRange.to; }
];
或者之前轉換它,以便我們可以省略(並且不需要重復調用) values
函數:
conditions = _.values(conditions);
現在您可以將代碼縮短到
var result = _.filter(numbers, function(current) {
return _.all(conditions, _.invokeWith(current));
});
理解發生的事情可能會更復雜,因為大多數人都必須查找invokeWith
函數,但是這個概念更容易理解,因為代碼是完全聲明的,包含構建自然表達式的所有動詞用current
調用所有條件 。
如果想要刪除外部lambda表達式,它會變得更短但更難理解:
// functional programming FTW :-)
var result = _.filter(numbers, _.compose(_.partial(_.all, conditions), _.invokeWith));
沒有必要重寫該代碼; 把它放在一個命名函數中:
function filterByConditions(values, conditions){
return _.filter(values, function(current) {
return _.all(_.values(conditions), function(f) {
return f(current);
});
});
}
函數中的代碼並不復雜,不應該與熟悉underscore.js的人混淆。 如果您認為有必要,可以在函數體中添加注釋。 無論哪種方式,當您在其他地方使用該函數時,應該清楚該函數從名稱中執行的操作:
var result = filterByConditions(numbers, conditions);
如果你想簡化函數的主體,那么不熟悉underscore.js的開發人員仍然可以讀取它,你可以用簡單的for ... in循環替換_all
和_values
。 大多數Javascript開發人員可以在沒有使用underscore.js的情況下推斷_.filter的作用:
function filterByConditions(values, conditions){
return _.filter(values, function(current){
for(condition_name in conditions){
if(!conditions[condition_name](current)){
// Condition failed
return false;
}
}
// All conditions passed
return true;
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.