본문 바로가기

자바스크립트 입문하기

[프로그래머스/JS] Level2 - 의상 #reduce() #Counter #Map

 

https://school.programmers.co.kr/learn/courses/30/lessons/42578

 

프로그래머스

SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

 

오늘은 reduce, Map를 가볍게 훑어보려구해요.

 

 

 

 

TIL

- reduce()
- Array.from() 과 스프레드 문법 " ... "
- Map, MapIterator
- Counter
- Swift는 nil이라는 값이 존재하지 않을 경우가 하나의 타입인데 JS는 undefined, null ..
  글해서 || 나 && 쓸때 '단축 평가' 적용해야하는데 뭔가 좀 문자와 문자가 피연산자일 때 적용하기 낯설음 Falsely
  당황스러운건 0 or 1, false or true 이게 아니라 값 자체를 반환한다.. 문자열이면 문자열,,
  JS 편한점은 배열 순회할 때 index까지 추가해준달까?

 

 

문제 풀이

입력값으로 의상-종류 가 주어집니다.

 

이 문제는 의상 종류별 개수 세는게 중요합니다.

 

옷을 입는 경우인데 이게 바지 안입고 안경 + 코트 이 두 경우만 입어도 입은 것으로 간주됩니다...

최소 하나 이상! 서로 다른 종류의 옷들을 입는 방법

 

옷을 입는 모든 경우의수 - 1(안입는 경우)을 해두 좋습니다.

 

const typeChecker = ((누적, [_, type]) => 
    누적.set(type, (누적.get(type) || 0) + 1)
)
const reducer = (prev, count) => prev * (count + 1)

function solution(clothes) {
    return Array.from(
        clothes
        .reduce (typeChecker, new Map())
        .values() // MapIterator 반환
    ).reduce(reducer, 1) - 1   
}

 

 

1. typeChecker라는 클로저는 Map 타입을 반환합니다. Map은 get함수와 키를 통해서 값을 가져올 수 있는데, 존재하지 않는 경우 undefined를 방출합니다. 이때 값이 없는 경우 기본 값을 아래처럼 지정할 수 있습니다.

 

undefined || 0 // undefined, null은 항상 Falsely 값이기에 왼쪽 아니면 오른쪽이 맞으면 오른쪽 값을 반환,,

 

 

그래서 옷 이름이 뭔지는 상관없고,, 어느 종류에 해당하는가의 개수를 샙니다. 

 

모든 옷을 하나 이상 입는 경우는 reducer와 같이, 개수 + 1 한 모든 각각의 값을 곱한 값 - 1(안 입는 경우) 하면 됩니다.

예를들어

바지 1개, 모자 1개인 경우

((1 + 1)* (1+1)) - 1 = 3이 됩니다. 

 

 

아래는 함수들 공부!

 

Map [ 링크 ]

얘는 딕셔너리

 

어 왜 prototype이 붙지,, 

공식 문서(MDN 등)에서 Map.prototype.set()이라고 표기하는 이유는 이 메서드의 정의가 어디에 있는지를 정확하게 알려주기 위함입니다.
Map이라는 생성자 함수(클래스)의 설계도인 prototype 객체 안에 set 함수가 정의되어 있다는 뜻이죠.이러한 방식으로 JS는 메모리 효율성을 높입니다. set 함수 코드는 메모리에 한 번만 존재하고, 모든 Map 인스턴스가 이 코드를 공유하여 사용하게 됩니다.
결론적으로, Map.prototype.set()은 'Map 인스턴스가 사용할 수 있는 set() 메서드'를 의미하며, 당신은 myMap.set()처럼 인스턴스를 통해 사용하시면 됩니다. 😊

 

Map.entries()는 Map에 저장된 모든 키-값 데이터를 훑을 수 있음 (Map Iterator 객체 반환) for of 루프 swift 는.. in 써야합니다.

Map.forEach() 함수 또한 동일하게 Map에 저장된 모든 키 값-데이터를 훑을 수 있습니다. 그러나 얘는 함수를 반복 실행하는거라 중간에 continue 대신 return을 써야하는데 이게 간혹가다가 for of 루프 쓸때가 더 좋을수도 있습니다.

 

Map.get() 데이터 있으면 가져오기 없으면 undefined. 이는 undefined || default value지정 가능

Map.keys() 모든 키들 순회가능한 Map iterator 반환 (cf. iterator는 Array.reduce() 이런 함수 없는 좀 많이 가벼운 느낌)

Map.has() Map안에 키 있으면 bool값 반환.. 

Map.values() 키가 아닌 값들만 Map Iterator 반환

 

keys(), values(), entries() 보면 알겠지만 Map Iterator를 반환한다. 그래서 reduce같은 함수를 쓰고 싶어도 쓸 수 없다. (참고로 Iterator는 프로토콜) 

그래서 Array.from()이나 [... 배열]이렇게 배열로 변환해서 써야한다.

 

reduce

reduce는 고차함수입니다. 고차함수는 객체지향 + 1급 객체를 지원하는데 그래서 위와 같은 코드가 가능합니다.

 

https://developer.mozilla.org/ko/docs/Glossary/First-class_Function

 

일급 함수 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

const foo = () => { console.log("foobar"); }; foo(); // 변수를 사용해 호출 // foobar 변수에 '익명함수'를 할당한 다음, 끝에 괄호 ()를 추가하면서 함수를 호출할 해당 변수를 사용합니다. 참고 : 함수가 이름

developer.mozilla.org

 

 

 

reduce는 아래 링크에 잘 나옵니다.

간단히 설명하자면

 

// 1부터 5까지 더해보겠습니다.

const reduce쓸때초기값 = 0
let res = [1,2,3,4,5].reduce( (누적으로더한값들, 순차적으로배열순회하는데_그때_Element값) => 
	return 누적으로 더한값들 + 순차적으로배열순회하는데_그때_Element값
    
), reduce쓸때초기값)

// res == 5

 

 

배열의 길이만큼, 총 5번의 함수가 호출됩니다. 

 

function 반복실행될함수(누적으로더한값들, 순차적으로배열순회하는데_그때_Element값) {
    return 누적으로더한값들 + 순차적으로배열순회하는데_그때_Element값
}

 

일급 함수의 특성상 변수나 상수로 지정도 가능하답니다. (맨 위에 문제 풀때 const처럼)

 

그래서 이 함수가 5번 실행되는겁니다. 실행된 결과는 누적으로 더한 값들에 저장됩니다. 그래서 누적으로 더한 값들의 초기값을 지정해야합니다. 

 

참고로 reduce에 사용되는 컬백함수는 (누적값, 순회하는요소, 순회할때몇번째원소인지Index, array) 이렇게까지 쓸수있습니다.

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

 

Array.prototype.reduce() - JavaScript | MDN

const array1 = [1, 2, 3, 4]; // 0 + 1 + 2 + 3 + 4 const initialValue = 0; const sumWithInitial = array1.reduce( (accumulator, currentValue) => accumulator + currentValue, initialValue, ); console.log(sumWithInitial); // Expected output: 10 리듀서 함수

developer.mozilla.org

 

 

References

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map

 

Map - JavaScript | MDN

Map 객체는 키-값 쌍인 집합입니다. 한 Map에서의 키는 오직 단 하나만 존재 합니다. 이는 Map 집합의 유일성입니다. Map 객체는 키-값 쌍으로 반복됩니다. for...of 루프는 각 반복에 대해 [key, value]로

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce

 

Array.prototype.reduce() - JavaScript | MDN

const array1 = [1, 2, 3, 4]; // 0 + 1 + 2 + 3 + 4 const initialValue = 0; const sumWithInitial = array1.reduce( (accumulator, currentValue) => accumulator + currentValue, initialValue, ); console.log(sumWithInitial); // Expected output: 10 리듀서 함수

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Glossary/First-class_Function

 

일급 함수 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

const foo = () => { console.log("foobar"); }; foo(); // 변수를 사용해 호출 // foobar 변수에 '익명함수'를 할당한 다음, 끝에 괄호 ()를 추가하면서 함수를 호출할 해당 변수를 사용합니다. 참고 : 함수가 이름

developer.mozilla.org

 

728x90