문제
첫 번째 패러미터는 객체들을 원소로 하는 배열이다. 두 번째 패러미터는 객체이다. 두 번째 패러미터인 객체의 key와 value를 똑같이 포함하고 있는 있는 객체들만 남겨서 리턴하라.
- 예시
whatIsInAName([{ "apple": 1, "bat": 2 }, { "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }], { "apple": 1, "bat": 2 }) // should return [{ "apple": 1, "bat": 2 }, { "apple": 1, "bat": 2, "cookie": 2 }].
내가 푼 답
function whatIsInAName(collection, source) { // What's in a name? var sourceKey = Object.keys(source) var sourceVal = Object.values(source) for(var i = 0 ; i < collection.length ; i++) { for(var j = 0 ; j < sourceKey.length ; j++) { if(!collection[i].hasOwnProperty(sourceKey[j]) || collection[i][sourceKey[j]] !== sourceVal[j]) { collection.splice(i,1); if(collection.length !== 0) { i -= 1; } else { return []; } } } } return collection; }
Intermediate Solution
function whatIsInAName(collection, source) { var srcKeys = Object.keys(source); return collection.filter(function (obj) { return srcKeys.every(function (key) { return obj.hasOwnProperty(key) && obj[key] === source[key]; }); }); }
filter의 리턴부분이 내가 헤맸던 부분!
collection 각 원소들의 key와 value가 source key, value와 일치하는지 확인하는 부분에서, source key를 순회하는 부분을 못했었는데(막혀서 spread operator를 시도했으나 에러가 났다), 또다시 every 메소드를 리턴해서 할 수 있는 것을 처음 알았다. every메소드는 sryKeys의 모든 key, value와 일치해야하기 때문에 사용되었다. 나는 처음에 includes를 활용했다가, 일부만 일치되어도 다 리턴해서 실패했었다.
Advanced Solution
function whatIsInAName(collection, source) { var srcKeys = Object.keys(source); // filter the collection return collection.filter(function (obj) { return srcKeys .map(function(key) { return obj.hasOwnProperty(key) && obj[key] === source[key]; }) .reduce(function(a, b) { return a && b; }); }); }