const arr = [1,2,3,4,5,6,7,8]
const count2 = arr.reduce( (ac, v) => {
v in ac ? ac[v]++ : ac[v] = 1
return ac;
}, {});
const count3 = arr.reduce( (ac, v) => {
ac[v] = ( ac[v] || 0 ) + 1
return ac
}, {})
const arr = [1,2,3,4,5,1]
const count = arr.reduce( (ac,v) => ({...ac, [v] : ( ac[v] || 0 ) + 1 }), 0)
console.log(count)
위커뮤니티에 올라온 글 중에 흥미로운 코드가 있어서 살펴보게 되었다
프로그래머스 풀 때 이런 논리를 기반으로 이것저것 선언,할당해서 코드가 길어지곤 했는데 이 기회에 reduce 메서드와 spread 연산자로 더 간단하게 짜는 법에 익숙해지고자 한다.
arr
의 값을 순회하여v
, 0
,(=> "",[], {} 여도 상관없음)ac
에 키 v
로 접근한 값이 없으면 0, 있으면 +1원문: ✅
const count = arr.reduce( (ac,v) => ({...ac, [v] : ( ac[v] || 0 ) + 1 }), 0)
화살표 다음에 괄호()
를 지우면? ❌
👉 왜 지우면 안될까?
const count = arr.reduce( (ac,v) => {...ac, [v] : ( ac[v] || 0 ) + 1 }, 0)
Uncaught SyntaxError: Rest parameter must be last formal parameter
추측: 화살표 함수의 규칙?
화살표 함수에서는{}
가 객체 자체를 반환하는 건지, 함수 블록인지 판단하기 어려우니까 객체 자체를 반환하는 거라면({})
처럼 묶어주는게 아닌가 싶다const a1 = x => ({...x}) function a2(x){ return {...x} } console.log(a1("a")) console.log(a2("a"))
화살표 함수를 function으로 쓰면 ✅
const count = arr.reduce( function(ac,v){
return ({ ...ac, [v] : ( ac[v] || 0 ) + 1 })
}, 0)
return 다음에 ()
를 지우면? ✅
const count = arr.reduce( function(ac,v){
return { ...ac, [v] : ( ac[v] || 0 ) + 1 }
}, 0)
const arr = [1,2,3,4,5]
const count4 = arr.reduce( (ac,v) =>
({ ...ac, [v] : ( ac[v] || 0 ) + 1 }), "abc")
console.log(count4)
"abc"를 spread 해서 {}
에 초기값으로 할당하면
ac = { "0":"a", "1":"b", "2":"c" }
ac[v]에 값이 있으면 ac[v]+1, 없으면 0+1
// v = 1 일 때 존재하므로 +1
ac = { "0":"a", "1":"b1", "2":"c" }
// v = 2 일 때 존재하므로 +1
ac = { "0":"a", "1":"b1", "2":"c1" }
// v = 3 일 때 없으므로 0+1
ac = { "0":"a", "1":"b1", "2":"c1", "3":1 }
// v = 4 일 때 없으므로 0+1
ac = { "0":"a", "1":"b1", "2":"c1", "3":1, "4":1 }
// v = 5 일 때 없으므로 0+1
ac = { "0":"a", "1":"b1", "2":"c1", "3":1, "4":1, "5":1 }
const arr = [1,2,3,4,5]
const count3 = arr.reduce( (ac,v) =>
({ [v] : ( ac[v] || 0 ) + 1, ...ac }), "abc")
console.log(count3)
ac[v]에 값이 있으면 ac[v]+1, 없으면 0+1
// v = 1 일 때 없으므로 0+1
ac = { "1":1 }
// v = 2 일 때 없으므로 0+1
ac = { "1":1, "2":1 }
// v = 3 일 때 없으므로 0+1
ac = { "1":1, "2":1, "3":1 }
// v = 4 일 때 없으므로 0+1
ac = { "1":1, "2":1, "3":1, "4":1 }
// v = 5 일 때 없으므로 0+1
ac = { "1":1, "2":1, "3":1, "4":1, "5":1 }
"abc"를 spread 해서 {}
에 할당하면
ac = { "0":"a", "1":"b", "2":"c", "3":1, "4":1, "5":1 }
다음 실행 결과는 { "0":"1", "1":"2" }
이 되어야 하지 않을까? 왜 "12"
일까?
arr에 상관없이 무조건 ac를 spread연산하는게 우선이라고 생각했는데
왜지.. arr에 값이 없거나 공백이면 초기값 그대로 산출되는 조건이 있나?
const arr = [] // [ ] 도 동일한 결과
const count1 = arr.reduce( function(ac,v){
return ({ ...ac, [v] : ( ac[v] || 0 ) + 1 }) }, "12")
const arr = [[]] // [""] 도 동일한 결과
const count1 = arr.reduce( function(ac,v){
return ({ ...ac, [v] : ( ac[v] || 0 ) + 1 }) }, "12")
const arr = [{}]
const count1 = arr.reduce( function(ac,v){
return ({ ...ac, [v] : ( ac[v] || 0 ) + 1 }) }, "12")