[1,2,3].forEach(function(el) {
if(el === 1) break;
});
forEach
JavaScript 에서 새로운 방법을 사용하여이 작업을 수행하려면 어떻게해야 합니까? 나는 시도했다 return;
, return false;
하고 break
. break
충돌하고 return
아무것도 반복하지 않습니다.
[1,2,3].forEach(function(el) {
if(el === 1) break;
});
forEach
JavaScript 에서 새로운 방법을 사용하여이 작업을 수행하려면 어떻게해야 합니까? 나는 시도했다 return;
, return false;
하고 break
. break
충돌하고 return
아무것도 반복하지 않습니다.
답변:
어떤이 내장되지-에서의 능력 break
에서 forEach
. 실행을 중단하려면 일종의 예외를 발생시켜야합니다. 예.
var BreakException = {};
try {
[1, 2, 3].forEach(function(el) {
console.log(el);
if (el === 2) throw BreakException;
});
} catch (e) {
if (e !== BreakException) throw e;
}
JavaScript 예외는 그리 예쁘지 않습니다. 내부에 for
정말로 필요한 경우 전통적인 루프가 더 적합 할 수 있습니다 break
.
Array#some
대신 다음을 사용하십시오 Array#some
.
[1, 2, 3].some(function(el) {
console.log(el);
return el === 2;
});
이것은 배열 순서로 실행 된 콜백이 있으면 즉시 some
반환 하고 나머지는 실행을 단락 시키므로 작동 합니다 .true
true
some
, 그 반대 every
(에서 멈춤 return false
) 및 누락 된 브라우저에 forEach
추가해야하는 모든 ECMAScript Fifth Edition 메소드입니다 Array.prototype
.
some
하고 every
,이 질문에 대해 답 TOP에 있어야합니다. 사람들이 왜 읽기 어렵다고 생각하는지 이해할 수 없습니다. 정말 대단해!
Array#some
이 정말 좋습니다. 첫째, ie9 및 firefox 1.5를 포함한 대부분의 브라우저와 호환 가능합니다. 내 사용 사례는 [a, b] 범위의 배열에서 인덱스를 찾는 것입니다. 여기서 숫자는 하한과 상한 쌍 사이에 있으며 테스트되면 true를 반환합니다. for..of
최신 브라우저에서만 다음으로 최고의 솔루션이 될 것입니다.
새로운 for of 루프를 사용하여 ECMAScript 2015 (일명 ES6)에서이 작업을 수행하는 더 좋은 방법이 있습니다. 예를 들어이 코드는 숫자 5 뒤에 배열 요소를 인쇄하지 않습니다.
let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (let el of arr) {
console.log(el);
if (el === 5) {
break;
}
}
문서에서 :
for ... in 및 for ... of 문 모두 무언가를 반복합니다. 그들 사이의 주요 차이점은 그들이 반복하는 것입니다. 을 위해 더 ... 문은 원래 삽입 순서로 객체의 열거 속성을 반복 처리. 는 의를 위해 ... 문이 데이터를 반복 처리 반복 가능한 객체를 정의는 이상 반복 할 것이다.
반복에 인덱스가 필요하십니까? 당신은 사용할 수 있습니다 Array.entries()
:
for (const [index, el] of arr.entries()) {
if ( index === 5 ) break;
}
entries
. for (someArray.entries ()의 const [index, element]) {// ...}
Object.entries(myObject)
를 사용 for..in
하면 배열에 대해 사용하는 것처럼 정확하게 사용할 수 있습니다 . JS 배열은 기본적으로 후드 아래의 객체입니다. blog.niftysnippets.org/2011/01/myth-of-arrays.html
모든 방법을 사용할 수 있습니다 :
[1,2,3].every(function(el) {
return !(el === 1);
});
ES6
[1,2,3].every( el => el !== 1 )
오래된 브라우저 지원을 위해 :
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;
};
}
[1,2,3].every( el => el !== 1 )
every
보장 합니까?
k
가 0에서 시작하고 1 씩 증가 한다는 알고리즘을 볼 수 있습니다 . http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.every
MDN 문서Array.prototype.forEach()
에서 인용 :
없다 중지 또는 중단 할 수있는 방법
forEach()
예외를 던지는 이외의 루프. 이러한 동작이 필요한 경우.forEach()
방법이 잘못된 도구 이므로 대신 일반 루프를 사용하십시오. 술어에 대해 배열 요소를 테스트하고 부울 리턴 값이 필요한 경우every()
또는some()
대신 사용할 수 있습니다 .
@bobince가 제안한대로 코드 (질문에)를 Array.prototype.some()
대신 사용하십시오. 사용 사례에 매우 적합합니다.
Array.prototype.some()
콜백이 진솔한 값 (a로 변환 될 때 참이되는 값)을 반환 할 때까지 배열에있는 각 요소에 대해 콜백 함수를 한 번 실행합니다Boolean
. 그러한 요소가 발견되면some()
즉시 true를 리턴합니다. 그렇지 않으면some()
false를 반환합니다. 콜백은 값이 할당 된 배열의 인덱스에 대해서만 호출됩니다. 삭제되었거나 값이 할당되지 않은 인덱스에 대해서는 호출되지 않습니다.
불행히도이 경우를 사용하지 않으면 훨씬 좋습니다 forEach
. 대신 일반 for
루프를 사용하면 예상대로 정확하게 작동합니다.
var array = [1, 2, 3];
for (var i = 0; i < array.length; i++) {
if (array[i] === 1){
break;
}
}
콜백 함수 내에서 false를 반환 할 수 있으므로 jquery
의 each
메소드 를 사용하는 것이 좋습니다 .
$.each(function(e, i) {
if (i % 2) return false;
console.log(e)
})
Lodash 라이브러리는 또한 takeWhile
map / reduce / fold 등과 연결될 수있는 방법을 제공합니다 :
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');
// => []
코드 예제에서 원하는 Array.prototype.find
것은 Array.prototype.find () 및 Array.prototype.findIndex ()입니다.
[1, 2, 3].find(function(el) {
return el === 2;
}); // returns 2
Dean Edward의 제안 을 사용 하고 StopIteration 오류를 발생시켜 오류를 포착하지 않고 루프를 벗어나려면 다음 함수를 사용할 수 있습니다 ( 원래 here ).
// 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;
}
}
};
}
})();
위의 코드는 자체 try-catch 절을 수행하지 않고도 다음과 같은 코드를 실행할 수있는 기능을 제공합니다.
// Show the contents until you get to "2".
[0,1,2,3,4].forEach(function(val) {
if(val == 2)
throw StopIteration;
alert(val);
});
기억해야 할 한 가지 중요한 사항은 Array.prototype.forEach 함수가 이미 존재하는 경우에만 업데이트한다는 것입니다. 존재하지 않는 경우 수정하지 않습니다.
짧은 대답 : for...break
이것을 사용 하거나 코드를 변경하여 코드가 손상되지 않도록하십시오 forEach
. 사용 .some()
하거나 .every()
에뮬레이션 하지 마십시오 for...break
. for...break
루프 를 피하려면 코드를 다시 작성하거나을 사용하십시오 for...break
. 당신이 for...break
대안으로 이러한 방법을 사용할 때마다 하나님은 고양이를 죽입니다.
긴 대답 :
.some()
그리고 .every()
모두 반환 boolean
값은, .some()
반환 true
에 대한 요소가 함수가 반환이 통과하는 경우 true
, 모든 반환 false
을위한 모든 요소는 함수가 반환이 통과하는 경우false
. 이것이 그 기능의 의미입니다. 의미하지 않는 기능을 사용하는 것은 코드를 읽는 모든 사람을 실망시키기 때문에 CSS 대신 레이아웃에 테이블을 사용하는 것보다 훨씬 나쁩니다.
또한 이러한 방법을 for...break
대안 으로 사용할 수있는 유일한 방법 은 부작용을 일으키는 것 ( .some()
콜백 함수 외부에서 일부 변수를 변경하는 것)이며 이는와 크게 다르지 않습니다 for...break
.
따라서 .some()
또는 루프 대안 .every()
으로 사용하면 for...break
부작용이 없으며, 이것은 훨씬 깨끗하지 않습니다.for...break
, 실망 스럽기 때문에 더 좋지 않습니다.
에 코드가 필요하지 않도록 언제든지 코드를 다시 작성할 수 있습니다 for...break
. 를 사용하여 배열을 필터링 하고 등을 .filter()
사용하여 배열을 분할 .slice()
한 다음 .forEach()
또는 .map()
배열의 해당 부분에 대해 또는를 사용하십시오.
for...break
는 성능이 필요한 경우 루프를 사용 합니다. for
루프는 가장 확대됨 반복 도구보다 .forEach()
, .any()
, .map()
, .filter()
등
이것은 문제를 해결하기 위해 생각해 낸 것입니다 ... 원래 질문자가 가지고있는 문제를 해결한다고 확신합니다.
Array.prototype.each = function(callback){
if(!callback) return false;
for(var i=0; i<this.length; i++){
if(callback(this[i], i) == false) break;
}
};
그런 다음 다음을 사용하여 호출합니다.
var myarray = [1,2,3];
myarray.each(function(item, index){
// do something with the item
// if(item != somecondition) return false;
});
콜백 함수 내에서 false를 반환하면 중단이 발생합니다. 실제로 작동하지 않는 경우 알려주십시오.
=== false
보다 나은 수 있습니다 == false
명시 적으로 일부 제어 경로가 값 예기치 않게 루프 휴식을 반환하지 않습니다 않도록, 루프를 계속하려면 true (또는 truthy 값)을 반환 할 필요가 없습니다.
내가 생각해 낸 또 다른 개념 :
function forEach(array, cb) {
var shouldBreak;
function _break() { shouldBreak = true; }
for (var i = 0, bound = array.length; i < bound; ++i) {
if (shouldBreak) { break; }
cb(array[i], i, array, _break);
}
}
// Usage
forEach(['a','b','c','d','e','f'], function (char, i, array, _break) {
console.log(i, char);
if (i === 2) { _break(); }
});
Array.prototype.forEach()
. for
그리고 break
이 질문은 질문을 받았다 오래 전에 존재; OP는보다 기능적인을 사용하여 해당 동작을 찾고있었습니다 forEach
.
for...in
및 break
.
다른 사이트에서이 솔루션을 찾았습니다. try / catch 시나리오에서 forEach를 랩핑 할 수 있습니다.
if(typeof StopIteration == "undefined") {
StopIteration = new Error("StopIteration");
}
try {
[1,2,3].forEach(function(el){
alert(el);
if(el === 1) throw StopIteration;
});
} catch(error) { if(error != StopIteration) throw error; }
자세한 내용은 여기 : http://dean.edwards.name/weblog/2006/07/enum/
반복 후에 배열에 액세스 할 필요가 없으면 배열의 길이를 0으로 설정하여 구제 할 수 있습니다. 반복 후에도 여전히 필요한 경우 slice를 사용하여 복제 할 수 있습니다.
[1,3,4,5,6,7,8,244,3,5,2].forEach(function (item, index, arr) {
if (index === 3) arr.length = 0;
});
또는 클론으로 :
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;
});
코드에서 임의의 오류를 발생시키는 것보다 훨씬 나은 솔루션입니다.
array.length
에 0
현재 반복에 적용됩니다 그들은, 그래서 아마 사용에 때때로 더 나은 return
같은 할당 한 후에
앞에서 언급했듯이 깰 수 없습니다 .forEach()
.
다음은 ES6 반복자로 foreach를 수행하는 약간 더 현대적인 방법입니다. 반복 할 때 index
/에 직접 액세스 할 수 있습니다 value
.
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!
forEach
구문 을 유지하려는 경우 이를 효율적으로 유지하는 방법입니다 (일반적인 for 루프만큼 좋지는 않지만). 루프에서 벗어날 지 알고있는 변수가 있는지 즉시 확인하십시오.
이 예는 생성하는 익명 함수를 사용하여 함수 영역 주위에 forEach
당신이 저장해야하는 완료 정보를.
(function(){
var element = document.getElementById('printed-result');
var done = false;
[1,2,3,4].forEach(function(item){
if(done){ return; }
var text = document.createTextNode(item);
element.appendChild(text);
if (item === 2){
done = true;
return;
}
});
})();
<div id="printed-result"></div>
내 두 센트
array.prototype.every
루핑을 끊을 수있는 유틸리티를 제공 하는 기능을 사용하십시오 . Mozilla 개발자 네트워크의 Javascript 문서를 보려면 여기를 참조하십시오.
@bobince에 동의하십시오.
또한 참고 :
Prototype.js는 이러한 목적으로 사용됩니다.
<script type="text/javascript">
$$('a').each(function(el, idx) {
if ( /* break condition */ ) throw $break;
// do something
});
</script>
$break
내부적으로 Prototype.js에 의해 처리되고 처리되므로 "각"주기는 중단되지만 외부 오류는 발생하지 않습니다.
자세한 내용은 Prototype.JS API 를 참조하십시오.
jQuery는 또한 루프를 일찍 깨기 위해 핸들러에서 false를 반환하는 방법이 있습니다.
<script type="text/javascript">
jQuery('a').each( function(idx) {
if ( /* break condition */ ) return false;
// do something
});
</script>
자세한 내용은 jQuery API 를 참조하십시오.
여전히 모든 요소를 순환하기 때문에 이것은 가장 효율적이지 않지만 매우 간단한 것을 고려해 볼 가치가 있다고 생각했습니다.
let keepGoing = true;
things.forEach( (thing) => {
if (noMore) keepGoing = false;
if (keepGoing) {
// do things with thing
}
});
continue
키워드이고 코드가 구문 오류입니다.
for of
하고 break;
있다면 평소 와 같이 루프로 전환해야합니다 .
아래 코드를 따라 나를 위해 일할 수 있습니다.
var loopStop = false;
YOUR_ARRAY.forEach(function loop(){
if(loopStop){ return; }
if(condition){ loopStop = true; }
});
경우와 같이 이미 배열에있는 요소의 값을 기준으로 중단 해야하는 경우 (즉, 중단 조건이 배열에 요소 값이 할당 된 후 변경 될 수있는 런타임 변수에 의존하지 않는 경우) 조합을 사용할 수도 있습니다 의 슬라이스 () 와 같이 IndexOf () 로서 다음과 같다.
forEach가 'Apple'에 도달했을 때 중단해야하는 경우
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
});
W3Schools.com에 명시된 것처럼 slice () 메서드는 선택한 요소를 배열의 새 배열 개체로 반환합니다. 원래 배열은 변경되지 않습니다.
JSFiddle 에서 참조하십시오
그것이 누군가를 돕기를 바랍니다.
당신은 변형을 만들 수 있습니다 forEach
즉 수 있습니다 break
, continue
, return
, 심지어 async
/ await
: (예 타이프로 작성)
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);
}
"find"로 시도하십시오.
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" }
예, forEach 루프를 계속하고 종료 할 수 있습니다.
계속하려면 return을 사용하면 루프가 계속되지만 현재 기능은 종료됩니다.
루프를 종료하려면 세 번째 매개 변수를 0 길이로 설정하고 빈 배열로 설정할 수 있습니다. 루프는 현재 기능이 계속되지 않으므로 "forturn"을 사용하여 일반 for 루프에서 종료하는 것처럼 마칠 수 있습니다.
이:
[1,2,3,4,5,6,7,8,9,10].forEach((a,b,c) => {
console.log(a);
if(b == 2){return;}
if(b == 4){c.length = 0;return;}
console.log("next...",b);
});
이것을 인쇄합니다 :
1
next... 0
2
next... 1
3
4
next... 3
5
전에 내 코드는 다음과 같습니다
this.state.itemsDataSource.forEach((item: any) => {
if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {
return false;
}
});
아래로 변경했는데 수정되었습니다.
for (var i = 0; i < this.state.itemsDataSource.length; i++) {
var item = this.state.itemsDataSource[i];
if (!item.isByPass && (item.invoiceDate == null || item.invoiceNumber == 0)) {
return false;
}
}
return
실제로 반복을 계속 하는 동안 블록에서 코드를 따라 오는 코드는 건너 뜁니다. 이 코드를 예로 들어[1,2,3].forEach(function(el) { if(el === 2) { console.log(`Match on 2!`); return; } console.log(el); });
봅시다 :console.log(el);
2가 일치하면 건너 뜁니다.