Array method reduce학습하기
Javascript30의 18번째 강의는 array method인 reduce()를 사용하여 비디오 리스트들의 시간 총합을 구하는 과정을 통해 reduce와 map등 array method에 대한 연습을 한다.
초기 코드는 다음과 같고 해당 코드를 확인해보면 <li> 태그들의 리스트가 작성되어있다. 모두 10분 미만의 시간을 data-item으로 가지고 있고, 이 시간들을 array method를 활용해 모두 합쳐볼 것이다.
const timeNodes = document.querySelectorAll('[data-time]');
console.log(timeNodes);
먼저 querySelectorAll을 통해 data-time속성을 가지고 있는 node들에 접근했다.
console을 통해 확인해보면
다음과 같이 노드들의 리스트를 확인할 수 있다.
리스트 접근이 가능해졌다면 다음은 javascript array method를 사용할 것이다. 먼저 querySelectorAll로 return받은 결과는 array가 아닌 nodeList이기 때문에 Array.from()을 통해 array상태로 만들어주고, map function을 통해 각 요소에 들어있는 data-time값들로 이루어진 배열을 만들었다.
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
const result = timeNodes.map(node => {
return node.dataset.time
});
console.log(result);
다음은 시간값들을 모두 합치기에 앞서 분과 초로 이루어진 배열의 결과값을 초로 환산해줄 것이다.
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
const result = timeNodes.map(node => {
return node.dataset.time
}).map(timeCode => {
const [mins, secs] = timeCode.split(':').map(parseFloat);
return (mins * 60) + secs;
});
console.log(result);
map함수를 통해 ‘:’를 기준으로 잘라 배열로 생성해주었고, 잘라진 배열의 각 요소는 string이기 때문에 parseFloat로 숫자로 바꾸어주었다. 그 다음은 분값에 60을 곱해 초로 환산하여 초값과 더해주었다.
reduce function은 누산기로서 배열의 각 요소값들을 이용해 하나의 단일값을 만들어준다. 파라미터로 받는 콜백함수는 두 개의 파라미터를 받는데, 첫 번째 인자는 accumulator, 즉 콜백의 반환값을 의미하고,
두 번째 인자는 해당 인덱스의 값(currentValue)를 의미한다. callback function뒤에는 선택적으로 initalValue를 넘겨줄 수도 있고, 만약 지정해주지 않는다면 배열의 첫번째 값 이사용된다.
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
const seconds = timeNodes.map(node => {
return node.dataset.time
}).map(timeCode => {
const [mins, secs] = timeCode.split(':').map(parseFloat);
return (mins * 60) + secs;
}).reduce((total, vidSeconds) => {
return total + vidSeconds;
});
console.log(seconds);
결과값으로 17938이라는 값이 출력된다.
결과값이 잘 출력되었다면 초로 표현된 시간의 총 합을 시분초로 표현할 것이다.
let secondsLeft = seconds;
const hours = Math.floor(secondsLeft / 3600);
secondsLeft = secondsLeft % 3600;
const mins = Math.floor(secondsLeft / 60);
secondsLeft = secondsLeft % 60;
console.log(hours, mins, secondsLeft);
로직상 어려운 부분은 없고 Math.floor function을 통해 소수점만 제거해주었다.
결과는 다음과 같이 출력된다.