2010-02-12 64 views
2

我正在試用函數式Javascript並遇到了一個有趣的情況。我有一個foreach函數需要一個集合和函數對象:如何打破函數式迭代?

var Utils = {}; 

// Applies a functor to each item in a collection. 
Utils.foreach = function(collection, functor) 
{ 
    for (var i = 0; i < collection.length; i++) 
    { 
    functor(collection[i]); 
    } 
}; 

這很酷。但是現在我要實現的另一個功能:

// Checks if a collection contains an item. 
Utils.has = function(collection, item) 
{ 
    Utils.foreach(collection, function(obj) { 
     if (item === obj) { 
      return true; // How to force a return from the foreach function? 
     } 
    }); 
    return false; 
}; 

正如你看到的,我不能執行「有」的功能,因爲我return語句不破迭代。

有人可以推薦這個問題的解決方案嗎?

+1

您需要使用閉包捕獲布爾標誌變量來指示是否應進一步處理項目,並根據需要翻轉標誌。 – 2010-02-12 22:17:46

+0

只需使用'Array.some'(https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/some)。 – kennytm 2010-02-12 22:22:14

+0

檢查jQuery的'each'方法。 – 2010-02-12 22:59:22

回答

2

我猜你想要的不是forEach,而是some(其他語言稱爲any)。本部分是​​(或其他語言的all)。您將在MDC上找到一個示例實現。

1

下面是一些真正快速和未經測試的東西(這是星期五4:50回家)。我會稍後嘗試測試並更新此帖子。看看這是否有幫助:

Utils = {}; 
Utils.foreach = function(collection, functor) { 
    loop: for (var i in collection) { 
     if (functor(collection[i])) { 
      alert("breaking the loop!"); 
      break loop; 
     } 
    } 
}; 
Utils.has = function(collection, item) { 
    var bolReturn = false; 
    Utils.foreach(collection, function(obj) { 
     if (item === obj) { 
      bolReturn = true; 
      return true; 
     } 
     return false; 
    }); 
    return bolReturn; 
}; 
Utils.has({"test":""}, ""); 
1

你需要對每個修改。

開始通過修改has

Utils.has = function (collection, item) { 
    var found = false; 
    Utils.foreach(collection, function (obj) { 
    if (item === obj) { 
     found = true; 
     return false; 
    } 
    }); 
    return found; 
}; 

然後,你需要修改forEach提前結束時,得到false

Utils.foreach = function (collection, functor) { 
    var prop; 
    for (prop in collection) { 
    if (prop.hasOwnProperty(prop)) { 
     if (functor(collection[prop]) === false) { 
     return; 
     } 
    } 
    } 
}; 
0

我不認爲你需要放棄你的結構 - 爲什麼不拋出並捕獲一個錯誤來打破循環?

Utils.has= function(collection, item){ 
    try{ 
     ControlCenter.foreach(collection, function(obj){ 
      if(item=== obj){ 
       throw 'found it!' 
      } 
     }); 
    } 
    catch(er){ 
     if(er== 'found it!') return true; 
    } 
    return false; 
};