면접에서 받았던, input으로 url을 받고 쿼리 부분을 object 혹은 JSON 형태로 바꾸는 함수 제작하기!!!
당일날에는 split을 많이 사용했었는데,
split으로 사용할 경우 0번째 인덱스 부터 n번째 인덱스까지 쭉 확인한다고 하셨다.
즉, url의 길이가 100이라고 가정했을 경우, split을 3번 사용하면 300번을 돌게 된다고...... 굉장히 메모리 효율이 떨어지는 방법이었다ㅠㅠ
이번에는 최대한 split을 최대한 적게 사용하려고 노력했다.
reduce는 Array method 중 하나로, 엘리먼트 하나하나에 대해 콜백함수를 적용시켜 하나의 결과값을 리턴해준다.
Array.reduce((acc,el)=>{
// do something with el
},initial_value)
acc는 accumulator로 accumulate는 누산, 축적 등의 의미를 지니고 있다.
즉, 이전까지의 결과값을 보관하고있다고 생각하면 될 것 같다.
initial_value에는 reduce 함수를 실행시킬 때 처음의 acc 값을 넣어준다.
const url = "http://localhost:3000?query=코로나&page=5";
const splitURL = (str) => {
let questionMarkIdx = 0;
let ampIdx = 0;
let i = 0;
while (i < str.length) {
if (str[i] === "?") {
questionMarkIdx = i;
}
if (str[i] === "&") {
ampIdx = i;
}
i++;
}
return [str.slice(questionMarkIdx + 1, ampIdx), str.slice(ampIdx + 1)]
.map((el) => {
return el.split("=");
})
.reduce((acc, el) => {
acc[el[0]] = el[1];
return acc;
}, {});
};
splitURL(url);
// result: { query: '코로나', page: '5' }
const url = "http://localhost:3000?query=코로나&page=5";
const splitURL = (str) => {
let questionMarkIdx = 0;
let ampIdx = 0;
let i = 0;
while (i < str.length) {
if (str[i] === "?") {
questionMarkIdx = i;
}
if (str[i] === "&") {
ampIdx = i;
}
i++;
}
const query = [str.slice(questionMarkIdx + 1, ampIdx), str.slice(ampIdx + 1)]
.map((el) => {
return el.split("=");
});
return Object.fromEntries(query);
};
splitURL(url);
[[key,value],....]
로 이루어진 배열을 Object로 변환시켜주는 object method를 찾아서 테스트해보았다. 뭔가 훨씬 편리해진 것 같기도 하고...
https://www.measurethat.net/Benchmarks/Show/9268/0/objectfromentries-vs-reduce
뭐가 더 빠를까에 대해 찾아보다가 위와 같은 사이트를 찾았다.
reduce와 fromEntries의 속도를 비교해두어서 실행시켜보았는데, 재미있는 결과를 찾을 수 있었다.
예전에 Vue 때 작성했던 Arrow Function 문법 중에, ()=>({})
로 객체를 리턴하게 하는 함수가 있었는데, 이걸로까지 redue함수를 만들어서 속도를 비교해주는 부분이 있었다.
그러니까 총 테스트 케이스가 세 가지!!!
결과가 재미있었다는 뜻은, 가장 빠른 것도 reduce, 가장 느린 것도 reduce였다는 점이다.
맨 위에서 작성한 코드처럼 acc를 return 하게끔 만드는 함수는 가장 빨랐고,
객체 자체를 리턴하면서 계속해서 acc를 풀어내도록 한 reduce는 가장 느렸다.
같은 메소드를 사용해도, 어떤 방식으로 리턴해주느냐에 대한 속도 차이가 났다는게 흥미로웠다 :)