문제 설명
코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.
예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.
코니는 각 종류별로 최대 1가지 의상만 착용할 수 있습니다. 예를 들어 위 예시의 경우 동그란 안경과 검정 선글라스를 동시에 착용할 수는 없습니다.
착용한 의상의 일부가 겹치더라도, 다른 의상이 겹치지 않거나, 혹은 의상을 추가로 더 착용한 경우에는 서로 다른 방법으로 옷을 착용한 것으로 계산합니다.
코니는 하루에 최소 한 개의 의상은 입습니다.
코니가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
코니가 가진 의상의 수는 1개 이상 30개 이하입니다.
같은 이름을 가진 의상은 존재하지 않습니다.
clothes의 모든 원소는 문자열로 이루어져 있습니다.
모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
입출력 예 설명
예제 #1
예제 #2
처음 푼 풀이
function solution(clothes) {
var answer = 0;
const
for ( let i = 0; i<clothes.length-1; i++) {
if ( clothes[i][1] !== clothes[i+1][1]) {
answer +1;
}
}
return answer + clothes.length;
}
왜이렇게 ,, 쉽지? 하면서 풀었는데 테스트는 통과하였으나 정확도가 굉장히 낮게 나와서 결론적으론 fail했다. 서치로 map 메서드를 사용해야한다는 정보를 얻고 두 번째 풀이.
function solution(clothes) {
const clothesMap = {};
let answer = 1;
// 의상 종류별로 갯수를 저장
clothes.forEach(arr => { //clothes 배열을 순회하면서 각 요소를 arr배열에 할당하고 코드 블록을 실행. arr은 clothes 배열의 각 요소를 나타내는 임시 변수
const [type, name] = arr;
if(clothesMap.hasOwnProperty(name)) { //clothesMap 객체에 name이라는 속성이 있는지 확인하는 조건문
clothesMap[name]++; //이미 존재한다면 해당 종류의 이상 개수를 1증가
}
else {
clothesMap[name] = 1; //객체에 해당 종류의 의상이 존재하지 않는 경우, 해당 의상이 처음으로 추가되는 것이므로 name 속성을 추가하고 1로 초기화
}
})
for(const key in clothesMap) {
// 해당 종류의 의상을 입지 않는 경우도 고려하여, 의상 개수에 1을 더한 값을 answer에 곱하기
//key는 각 속성의 이름을 나타내는 변수. clothesMap 객체에 저장된 의상 종류별 개수를 처리하는 역할
answer *= (clothesMap[key] + 1); //clothesMap[key]는 key에 해당하는 속성 값, 즉 의상 종류별 개수를 나타냄.
}
// 모든 종류의 의상에 대한 처리가 완료되면, 모든 의상을 입지 않는 경우를 제외하기 위해 answer에서 1을 빼고 반환
return answer - 1;
}
해시란 해시 함수에서 얻어지는 값은 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수이다. 큰 파일에서 중복되는 레코드를 찾을 수 있기 때문에 데이터 검색이나 테이블 검색의 속도를 가속한다. 아래는 간단한 해시함수 예시이다.
const animal = {};
animal['dog'] = 'doggy' ;
animal['cat'] = 'kitty' ;
위 코드는 string 자료형의 key에 해당하는 공간을 string 자료형의 value를 집어넣은 것이다. 이렇게 키와 값 형태로 데이터를 저장하는 구조를 object나 map으로 구현가능하다.
forEach는 배열 메서드로 이전에 MDN링크를 걸어둔 적 있다. 수기 타이핑으로 내가 이해한 개념을 정리해 보자면, 이 메서드는 배열의 각 요소에 대해 지정된 콜백 함수를 순차적으로 실행한다.
foreach 메서드는 다음과 같은 구문으로 사용된다.
array.forEach(callback(currentValue[, index[, array]])[, thisArg]);
ex)
const array = [1, 2, 3, 4, 5];
array.forEach((element) => {
console.log(element);
});
위 예시에서는 배열 array의 각 요소를 출력하기 위해 forEach를 사용했다.
forEach 메서드의 콜백 함수는 element 매개변수를 통해 현재 요소의 값을 받아와서 console.log로 출력한다. 결과적으로 1부터 5까지의 숫자가 순서대로 출력됩니다.
forEach 메서드는 반복문의 편리한 대안으로 사용될 수 있으며, 배열의 각 요소에 접근하고 작업을 수행하는 데 유용합니다.
hasOwnProperty는 JavaScript 객체의 메서드 중 하나로, 이 메서드는 객체가 특정 속성(프로퍼티)을 직접 소유하고 있는지를 확인하는 데 사용된다.
object.hasOwnProperty(property)
object: 확인할 속성이 있는 객체.
property: 확인할 속성의 이름(문자열).
hasOwnProperty 메서드는 객체에 property로 지정한 이름의 속성이 직접 포함되어 있는 경우에만 true를 반환하고, 상속받은 속성이나 프로토타입 체인에 속한 속성의 경우 false를 반환한다.
예를 들어, 다음은 hasOwnProperty를 사용하여 객체의 속성 유무를 확인하는 예시이다
const person = {
name: 'John',
age: 30,
};
console.log(person.hasOwnProperty('name')); // true
console.log(person.hasOwnProperty('age')); // true
console.log(person.hasOwnProperty('gender')); // false