Javascript 短路Array.forEach类呼叫中断
如何在JavaScript中使用新的Javascript 短路Array.forEach类呼叫中断,javascript,arrays,foreach,Javascript,Arrays,Foreach,如何在JavaScript中使用新的forEach方法实现这一点?我试过return,返回false和中断中断崩溃并且返回除了继续迭代之外什么都不做。在forEach中没有内置的中断功能。要中断执行,您必须抛出某种异常。例如 var BreakException={}; 试一试{ [1,2,3].forEach(函数(el){ 控制台日志(el); 如果(el==2)抛出BreakException; }); }捕获(e){ 如果(e!==BreakException)抛出e; }考虑使用jq
forEach
方法实现这一点?我试过return
,返回false代码>和中断
<代码>中断
崩溃并且返回
除了继续迭代之外什么都不做。在forEach
中没有内置的中断
功能。要中断执行,您必须抛出某种异常。例如
var BreakException={};
试一试{
[1,2,3].forEach(函数(el){
控制台日志(el);
如果(el==2)抛出BreakException;
});
}捕获(e){
如果(e!==BreakException)抛出e;
}
考虑使用jquery
的每个方法,因为它允许在回调函数中返回false:
[1,2,3].forEach(function(el) {
if(el === 1) break;
});
Lodash库还提供了可以与map/reduce/fold等链接的方法:
$.each(function(e, i) {
if (i % 2) return false;
console.log(e)
})
在另一个站点上找到此解决方案。您可以在try/catch场景中包装forEach
var users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']
// The `_.matches` iteratee shorthand.
_.takeWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['barney']
// The `_.matchesProperty` iteratee shorthand.
_.takeWhile(users, ['active', false]);
// => objects for ['barney', 'fred']
// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active');
// => []
此处有更多详细信息:如果您希望使用并抛出StopIteration错误来中断循环,而不必捕获错误,则可以使用以下函数():
上述代码将使您能够运行以下代码,而无需执行自己的try-catch子句:
// Use a closure to prevent the global namespace from be polluted.
(function() {
// Define StopIteration as part of the global scope if it
// isn't already defined.
if(typeof StopIteration == "undefined") {
StopIteration = new Error("StopIteration");
}
// The original version of Array.prototype.forEach.
var oldForEach = Array.prototype.forEach;
// If forEach actually exists, define forEach so you can
// break out of it by throwing StopIteration. Allow
// other errors will be thrown as normal.
if(oldForEach) {
Array.prototype.forEach = function() {
try {
oldForEach.apply(this, [].slice.call(arguments, 0));
}
catch(e) {
if(e !== StopIteration) {
throw e;
}
}
};
}
})();
需要记住的一点是,这只会更新Array.prototype.forEach函数(如果它已经存在)。如果它不存在,它将不会修改它。您可以使用以下方法:
ES6
对于旧浏览器支持,请使用:
[1,2,3].every( el => el !== 1 )
if(!Array.prototype.every)
{
Array.prototype.every=函数(fun/*,thisp*/)
{
var len=此长度;
如果(乐趣的类型!=“功能”)
抛出新的TypeError();
var thisp=参数[1];
对于(变量i=0;i
更多细节。这只是我想出的解决问题的办法。。。我很确定它解决了最初询问者的问题:
if (!Array.prototype.every)
{
Array.prototype.every = function(fun /*, thisp*/)
{
var len = this.length;
if (typeof fun != "function")
throw new TypeError();
var thisp = arguments[1];
for (var i = 0; i < len; i++)
{
if (i in this &&
!fun.call(thisp, this[i], i, this))
return false;
}
return true;
};
}
在回调函数中返回false将导致中断。如果这实际上不起作用,请告诉我。简短回答:使用来…中断
,或者更改您的代码以避免中断每个
。不要使用.some()
或.every()
来模拟的…中断
。重写代码以避免for…break
循环,或使用for…break
。每次你使用这些方法,比如说,for…break
alternative上帝会杀死小猫
长答覆:
.some()
和.every()
都返回布尔值,.some()
返回true
如果有传递函数返回true
的元素,则每个元素返回false
如果有传递函数返回false
的元素。这就是函数的含义。将函数用于它们并不意味着的内容比将表用于布局而不是CSS要糟糕得多,因为这会让所有阅读您代码的人都感到沮丧
var x = [1,3,4,5,6,7,8,244,3,5,2];
x.slice().forEach(function (item, index, arr) {
if (index === 3) arr.length = 0;
});
另外,将这些方法用作for…break
替代方法的唯一可能方法是产生副作用(在.some()
回调函数之外更改一些变量),这与for…break
没有太大区别
因此,使用.some()
或.every()
作为for…break
循环替代方案并不是没有副作用的,这比for…break
要干净得多,这是令人沮丧的,所以也不是更好
您可以随时重写代码,这样就不需要在中使用…break
。您可以使用.filter()
过滤数组,您可以使用.slice()
等拆分数组,然后对数组的该部分使用.forEach()
或.map()
。我提出的另一个概念:
函数forEach(数组,cb){
var应该中断;
函数_break(){shouldBreak=true;}
对于(变量i=0,界限=array.length;i我使用nullhack就是为了这个目的,它试图访问null
的属性,这是一个错误:
var myarray = [1,2,3];
myarray.each(function(item, index){
// do something with the item
// if(item != somecondition) return false;
});
试试看{
[1,2,3,4,5]
弗雷奇先生(
功能(val、idx、arr){
如果(val==3)null.NULLBREAK;
}
);
}捕获(e){
//e TypeError:null没有属性
}
//
如果迭代后不需要访问数组,可以通过将数组的长度设置为0来退出。如果迭代后仍然需要它,可以使用slice克隆它
try {
[1,2,3,4,5]
.forEach(
function ( val, idx, arr ) {
if ( val == 3 ) null.NULLBREAK;
}
);
} catch (e) {
// e <=> TypeError: null has no properties
}
//
或使用克隆:
[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
if (index === 3) arr.length = 0;
});
这是一个比在代码中抛出随机错误更好的解决方案。使用数组.prototype.each
函数,它为您提供了打破循环的实用工具。参见此处示例同意@bobince,向上投票
var x = [1,3,4,5,6,7,8,244,3,5,2];
x.slice().forEach(function (item, index, arr) {
if (index === 3) arr.length = 0;
});
此外,供参考:
Prototype.js为此提供了一些功能:
const Book = {"Titles":[
{"Book3" : "BULLETIN 3"},
{"Book1" : "BULLETIN 1"},
{"Book2" : "BULLETIN 2"}
]}
const findbystr = function(str) {
Book.Titles.forEach(function(data) {
if (typeof data[str] != 'undefined') {
return data[str];
}
}, str)
}
book = findbystr('Book1');
console.log(book);
有关详细信息,请参阅。现在,在ECMAScript 2015(又称ES6)中,使用新的。例如,此代码不打印数字5之后的数组元素:
让arr=[0,1,2,3,4,5,6,7,8,9,10];
对于(让el代表arr){
控制台日志(el);
如果(el==5){
打破
}
}
不幸的是,在这种情况下,如果不使用forEach
,效果会更好。
相反,使用常规的for
循环,现在它将完全按照您的预期工作
<script type="text/javascript">
jQuery('a').each( function(idx) {
if ( /* break condition */ ) return false;
// do something
});
</script>
var数组=[1,2,3];
对于(var i=0;i
如果您想保持forEach
语法,这是一种保持其效率的方法(尽管不如常规for循环好)。立即检查一个变量,该变量知道
var x = [1,3,4,5,6,7,8,244,3,5,2];
x.slice().forEach(function (item, index, arr) {
if (index === 3) arr.length = 0;
});
const Book = {"Titles":[
{"Book3" : "BULLETIN 3"},
{"Book1" : "BULLETIN 1"},
{"Book2" : "BULLETIN 2"}
]}
const findbystr = function(str) {
Book.Titles.forEach(function(data) {
if (typeof data[str] != 'undefined') {
return data[str];
}
}, str)
}
book = findbystr('Book1');
console.log(book);
<script type="text/javascript">
$$('a').each(function(el, idx) {
if ( /* break condition */ ) throw $break;
// do something
});
</script>
<script type="text/javascript">
jQuery('a').each( function(idx) {
if ( /* break condition */ ) return false;
// do something
});
</script>
var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
if (array[i] === 1){
break;
}
}
let keepGoing = true;
things.forEach( (thing) => {
if (noMore) keepGoing = false;
if (keepGoing) {
// do things with thing
}
});
var loopStop = false;
YOUR_ARRAY.forEach(function loop(){
if(loopStop){ return; }
if(condition){ loopStop = true; }
});
[1, 2, 3].find(function(el) {
return el === 2;
}); // returns 2
var arr = [1,2,3];
for (var i = 0, el; el = arr[i]; i++) {
if(el === 1) break;
}
const array = ['one', 'two', 'three'];
for (const [index, val] of array.entries()) {
console.log('item:', { index, val });
if (index === 1) {
console.log('break!');
break;
}
}
item: { index: 0, val: 'one' }
item: { index: 1, val: 'two' }
break!
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var fruitsToLoop = fruits.slice(0, fruits.indexOf("Apple"));
// fruitsToLoop = Banana,Orange,Lemon
fruitsToLoop.forEach(function(el) {
// no need to break
});
var myCategories = [
{category: "start", name: "Start", color: "#AC193D"},
{category: "action", name: "Action", color: "#8C0095"},
{category: "exit", name: "Exit", color: "#008A00"}
];
function findCategory(category) {
return myCategories.find(function(element) {
return element.category === category;
});
}
console.log(findCategory("start"));
// output: { category: "start", name: "Start", color: "#AC193D" }
var wageType = types.filter(function(element){
if(e.params.data.text == element.name){
return element;
}
});
console.dir(wageType);
export type LoopControlOp = "break" | "continue" | ["return", any];
export type LoopFunc<T> = (value: T, index: number, array: T[])=>LoopControlOp;
Array.prototype.ForEach = function ForEach<T>(this: T[], func: LoopFunc<T>) {
for (let i = 0; i < this.length; i++) {
const controlOp = func(this[i], i, this);
if (controlOp == "break") break;
if (controlOp == "continue") continue;
if (controlOp instanceof Array) return controlOp[1];
}
};
// this variant lets you use async/await in the loop-func, with the loop "awaiting" for each entry
Array.prototype.ForEachAsync = async function ForEachAsync<T>(this: T[], func: LoopFunc<T>) {
for (let i = 0; i < this.length; i++) {
const controlOp = await func(this[i], i, this);
if (controlOp == "break") break;
if (controlOp == "continue") continue;
if (controlOp instanceof Array) return controlOp[1];
}
};
function GetCoffee() {
const cancelReason = peopleOnStreet.ForEach((person, index)=> {
if (index == 0) return "continue";
if (person.type == "friend") return "break";
if (person.type == "boss") return ["return", "nevermind"];
});
if (cancelReason) console.log("Coffee canceled because: " + cancelReason);
}
traverseTree(doc): Promise<any> {
return new Promise<any>((resolve, reject) => {
this.gridOptions.api.forEachNode((node, index) => {
//the above function is the one I want to short circuit.
if(node.data.id === doc.id) {
return resolve(node);
}
});
});
}
this.traverseTree(doc).then((result) => {
this.doSomething(result);
});