2017-04-22 2 views
2

약간 혼란스러워서 freeCodeCamp에 도전하고 있습니다. 술어 (초 인수가) 모음 (첫 번째 인수)의 모든 요소에 truthy 경우forEach/for ... 값을 반환하지 않습니까?

모든 것이

확인 사실 다음과 같이

challenge는 읽습니다.

해결되었지만 추가 조치를 취해야하는 이유가 무엇인지 이해할 수 없습니다. 내 코드는 다음과 같은 수 있습니다 : collection 내에서 두번째 요소는 sex 속성을 갖고 있지 않기 때문에

function truthCheck(collection, pre) { 
    collection.forEach(function(element) { 
     for (key in element) { 
      if (!element.hasOwnProperty(pre)) { 
       return false; 
      } else if (key === pre) { 
       if (!Boolean(element[key])) { 
        return false; 
       } 
      } 
     } 
    }); 
    return true; 
} 

truthCheck([ 
    {"user": "Tinky-Winky", "sex": "male"}, 
    {"user": "Dipsy"}, 
    {"user": "Laa-Laa", "sex": "female"}, 
    {"user": "Po", "sex": "female"} 
], "sex"); 

그래서이 경우에 실패합니다. 또한 pre 인수 또는이 경우 sex이 true 값이 아닌 경우 실패합니다.

이들이 히트를 치면 (콘솔 로그를 통해 알 수 있습니다) 루프에서 빠져 나와 truthCheck 함수에서 돌아 오는 것으로 나타났습니다 .....하지만 그렇지 않습니다. 결국 사실로 돌아올 것입니다.

변수를 정의한 다음 그 값을 false로 설정하고 끝에서 변수를 반환함으로써이를 회피 할 수있었습니다. 더 좋은 방법이 있습니까? 이러한 반품이 truthCheck 함수에서 벗어나는 것 같습니다. 내가 놓친 게 있니?

+0

Foreach는 반환 값을 사용하여 아무 작업도 수행하지 않습니다. 대신에 for 회 돌이를 사용하고 싶을 것이다. – Christopher

+0

FYI :'if (Boolean (element [key]))'는'if (element [key])'로 작성하기 쉽습니다. 특정 값이 true로 평가되는 값으로 설정되어 있는지 확인합니다. 객체가 특정 * key * (특정 * value *를 가지는 것과 반대)를 가지고 있는지 알고 싶다면'if (element.hasOwnProperty (key)) '를 사용하십시오. – Tomalak

답변

2

, 이것은 의미가 없다 : array#forEach 단순히 않습니다

collection.forEach(function() { 
    // do something 
    return false; 
}); 

때문에 작업자 함수의 반환 값을 고려하지 않습니다. 단지 각 배열 요소에 대한 작업자 함수를 실행합니다.

function truthCheck(collection, pre) { 
    var allAreTruthy = true; 
    collection.forEach(function (elem) { 
    // if this ever flips allAreTruthy to false, it will stay false 
    allAreTruthy = allAreTruthy && elem[pre]; 
    }); 
    return allAreTruthy; 
} 

을하지만이 표현하는 더 나은 방법이 있습니다

당신은 외부 변수를 설정하는 작업자의 기능을 사용할 수 있습니다.

조건부 (두 번째 인수)가 컬렉션의 모든 요소 (첫 번째 인수)에 대해 true인지 확인하십시오.

으로 의역 할 수 없습니다 "컬렉션의 모든 요소가 특정 키에 truthy 값을가집니다."

function truthCheck(collection, pre) { 
    return collection.every(function (elem) { return elem[pre]; }); 
} 

는 "컬렉션의 요소 특정 키에 falsy 값 (또는 전체 키 누락) 없음. '으로 부연 설명 될 수 있습니다

또는, Array#none 방법은 실제로 존재하지 않기 때문에, "이 특정 키에 falsy 값이 컬렉션의하지 일부 요소이다."

function truthCheck(collection, pre) { 
    return !collection.some(function (elem) { return !elem[pre]; }); 
} 

Array#some 사용의 장점은 즉시이 충족 위해 추구하는 조건으로 반복 배열을 중단한다는 것이다. 배열에 요소가 많으면 성능이 향상됩니다. 짧은 배열의 경우 Array#every 또는 Array#forEach을 사용하면 많은 차이가 없습니다. 당신이 hasOwnProperty에 대한 검사가 여기에 불필요 설정되지 않은 키에 액세스 할 때 JS 객체는 단순히 undefined를 반환하기 때문에

위는

function truthCheck(collection, pre) { 
    var i; 
    for (i = 0; i < collection.length; i++) { 
    if (!collection[i][pre]) return false; 
    } 
    return true; 
} 

의미 상 동일합니다.

2

컬렉션의 각 요소에 대해 함수를 실행합니다. 이 함수는 해당 요소가 무언가를 반환하는지 확인합니다. 그러나 그 반환 값은 외부 함수의 결과에 영향을 미치지 않습니다. 외부 함수는 내부 함수에 의존하지 않으므로 결과는 항상 사실입니다.

변수를 정의한 경우이 변수를 false로 설정하면 끝에있는 해당 변수가 작동하지만 비효율적입니다. 다음 시나리오를 생각해 봅시다. 대상 키가없는 요소 하나를 발견했습니다. 그래서 지금 당장 돌아와야하지만 할 수는 없습니다. 전체 컬렉션을 통해 스스로 작업해야합니다. forEach 루프는 mess없이 종료 할 수있는 기회를 제공하지 않습니다. 따라서 더 좋은 아이디어는 루프에 대한 입니다. 귀하의 캔 출구 출구는 루프에 대한 약간 쉬운 방법이 될 것입니다 당신이

찾고 있던 찾을 경우 :

function truthCheck(collection, pre) { 
    //iterate thrugh your collection 
    for (var c in collection){ 
     //get keys of element as an array and check if pre is in that array 
     if(Object.keys(collection[c]).indexOf(pre) == -1){ 
      // pre was not found 
      return false; 
     } 
    } 
    return true; 
} 
2
function truthCheck(collection, pre) { 
    return collection.every(function (person) { return !!person[pre]; }); 
} 
+0

'return person [pre];'는 진리 검사를하기에 충분합니다. – Tomalak

+0

Tomalak 맞아, 방금 형식 일관성을 유지하기 위해 부울로 변환했습니다. –

+0

'every every'에 관해서는 아무런 차이가 없다고 생각됩니다. :) – Tomalak

2

자바 스크립트의 [컬렉션] .forEach는 일반 루프처럼 작동하지 않습니다. 당신이 예외를 던지지 않는 한 그것을 조기에 종료 할 수있는 방법은 없습니다.

당신이 기대하는 동작은 자바 스크립트 for 루프에서 기대할 수있는 것이지만 forEach는 각 반복 된 객체에 대해 콜백 함수를 사용하므로 forEach 대신 콜백 함수를 종료합니다. 또한 코드에서 리턴 값을 가진 for 루프를 사용하는 것이 중요합니다. 이 루프의 리턴 블록은 forEach가 아닌이 루프 만 중단합니다 (앞에서 언급했듯이 다르기 전에 조기에 종료 할 수 없음)

forEach에서 볼 수 있듯이 forEach는 대부분 반복되는 조건부 검사 대신 모든 요소를 ​​반복하는 것을 의미합니다 요소.

1

ForEach 루프에서 아무 것도 반환 할 수 없습니다. 기본적으로 undefined을 반환합니다. 공식 문서로

, Array.prototype.forEach() - JavaScript | MDN는 말한다 :

중지하거나 예외를 던지기보다는 다른 foreach는() 루프를 중단하는 방법은 없습니다. 이러한 동작이 필요한 경우 forEach() 메서드가 잘못된 도구이므로 대신 일반 루프를 사용하십시오. 술어에 대한 배열 요소를 테스트하고 부울 반환 값이 필요한 경우 every() 또는 some()을 대신 사용할 수 있습니다.

그래서 당신은 예를 들어, 매우 간단한 for..in 루프를 사용할 수 있습니다 다른 답변이 설명으로

for(var c in collection){ 
    // Do whatever you want 
} 
관련 문제