[ํด๋ผ์ฐ๋ฉ ์ดํ๋ฆฌ์ผ์ด์ ์์ง๋์ด๋ง TIL] 240124 - ๊ณ ์์ด ์ฌ์ง ๊ฒ์ ๊ณผ์ ํ ์คํธ, ์ฝ๋ฉํ ์คํธ
Intro
์ค๋์ ๊ฐ์๋ ์๋ฃ๊ณ ํ ์คํธ๋ง ํ์๋ค.
4์๊ฐ์ง๋ฆฌ ๊ณผ์ ํ ์คํธ๋ง ํ์ด๋ ํ๋ค๋ค. ์๊ธฐ ์ ์ ์ฝ๋ฉํ ์คํธ ๋ฌธ์ ๋ 3๋ฌธ์ ํ์๋ค.
๋ง์ง๋ง ๋ฌธ์ lv2 ํ๋ ค๋ค๊ฐ ํ๋ค์ด์ ๋ด์ผ๋ก ๋ฏธ๋ค๋ค ใ ใ
์ค๋ ํ์ตํ ๋ด์ฉ
: ๊ณผ์ ํ ์คํธ์ ์ฝ๋ฉํ ์คํธ ํ์ด๋ณด๊ธฐ
์ดํ ์ ์ ํ์๋ ๊ณ ์์ด ๋ฌธ์ ์ ์กฐ๊ธ ๋ค๋ฅธ.. ๊ณ ์์ด ์ฌ์ง ๊ฒ์๊ธฐ ๋ฌธ์ ๋ฅผ ํ์๋ค. ์ง๋ ๋ฌธ์ ๋ค๊ณผ ๋น์ทํ ๊ตฌํ ๋ฌธ์ ๋ ์์๊ณ ์๋ก์ด ๋ฌธ์ ๋ ์์๋ค. ์ด๋ฒ ๋ฌธ์ ์์ index.html์ ๊ตฌํ๋ ์์๋ค์ ์ปดํฌ๋ํธํํ๋ ์์ ๋ถํฐ ์์ํ๋ค.
์๋กญ๊ฒ ํ์ด ๋ณธ ๋ฌธ์ ๋ค๋ง ๋ฆฌ๋ทฐํด๋ณด์๋ค.
๊ฒ์์ด ์ถ์ฒ
[ํ์] ์ถ์ฒ ๊ฒ์์ด API๋ฅผ ์ด์ฉํด ์ ๋ ฅ๋์ ์ถ์ฒ ๊ฒ์์ด๋ฅผ ๋ณด์ฌ์ฃผ์ธ์. ์ถ์ฒ ๊ฒ์์ด๋ ์ํฐ๋ฅผ ์น๋ ๋ฑ ๋ณ๋์ ํ์๊ฐ ์์ ๋์๋ ์๋์ผ๋ก ๋ณด์ฌ์ผ ํฉ๋๋ค.
โ keywords๋ผ๋ class ๋ช ์ผ๋ก ์คํ์ผ๋ง ๋์ด์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ index.html๊ณผ style.css๋ฅผ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
โ API์ ๋ํ ์ค๋ช ์ ํ๋จ์ ์์ต๋๋ค.
โ API์์ ์๋ฌ๊ฐ ๋๊ฑฐ๋, ์ถ์ฒ ๊ฒ์์ด๊ฐ ์๋ ๊ฒฝ์ฐ์๋ ๊ฒ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๋ฐ์๋ ๋ฌธ์ ๊ฐ ์์ด์ผ ํฉ๋๋ค.
๊ฒ์์ด ์ถ์ฒ - ์ฌ์ฉ์ฑ ๊ฐ์
ํค๋ณด๋์ ๋ง์ฐ์ค๋ฅผ ์ด์ฉํด์ ์ถ์ฒ ๊ฒ์์ด๋ฅผ ์ ํํ ์ ์๊ฒ ๋ง๋ค์ด ์ฃผ์ธ์.
1๏ธโฃ esc๋ฅผ ๋๋ฅด๋ฉด ์ถ์ฒ ๊ฒ์์ด ์ฐฝ์ด ๋ซํ๋๋ค.
2๏ธโฃ ํค๋ณด๋์ ์, ์๋ ํค๋ฅผ ๋๋ฅด๋ฉด ์ถ์ฒ ๊ฒ์์ด ํ์ด๋ผ์ดํธ๊ฐ ์ฎ๊ฒจ์ง๊ณ ์ํฐ๋ฅผ ๋๋ฅด๋ฉด ํ์ด๋ผ์ดํธ๊ฐ ์์นํ ๊ฒ์์ด๊ฐ ์ ๋ ฅ์ฐฝ์ ๋ฐ์๋๊ณ ์ฌ์ง์ด ๊ฒ์๋ฉ๋๋ค.
3๏ธโฃ ๋ง์ฐ์ค๋ก ๋ค๋ฅธ ๊ณณ์ ํด๋ฆญํ์ฌ input์ด focus๋ฅผ ์์ด๋ฒ๋ฆฌ๋ ๊ฒฝ์ฐ ์ถ์ฒ ๊ฒ์์ด ์ฐฝ์ด ๋ซํ๋๋ค.
4๏ธโฃ ๋ง์ฐ์ค๋ก ์ถ์ฒ ๊ฒ์์ด๋ฅผ ๋๋ฅด๋ฉด ์ปค์๊ฐ ์์นํ ๊ฒ์์ด๊ฐ ์ ๋ ฅ์ฐฝ์ ๋ฐ์๋๋ฉฐ ์ฌ์ง์ด ๊ฒ์๋ฉ๋๋ค.
์์ ๋ฌธ์ ์์ ํ์ ๊ตฌํ๊ณผ 1, 3, 4๋ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
2๋ฒ์ ๋ชป ํ์๋ค. ํ์ด๋ณด๋ ค๊ณ ํ๋๋ฐ ์๊ฐ ๋ถ์กฑ + ํ๋ค๊ฐ ๋งํ์ ํฌ๊ธฐ.. ใ ํด์ค ๊ฐ์ ๋ค์ด๋ด์ผ๊ฒ ๋ค.
- Keywords.js
class Keywords {
data = {
items: [],
}
constructor({ $target, onSelectKeyword }) {
this.$keywordsContainer = document.createElement('div')
this.$keywordsContainer.className = 'keywords'
this.$keywordsList = document.createElement('ul')
this.$keywordsContainer.appendChild(this.$keywordsList)
$target.appendChild(this.$keywordsContainer)
this.onSelectKeyword = onSelectKeyword
}
setState(newData) {
this.data = { ...this.data, ...newData }
this.render()
}
showKeywordList() {
this.$keywordsContainer.style.display = 'block'
}
hideKeywordList() {
this.$keywordsContainer.style.display = 'none'
}
render() {
if(this.data.items) {
this.$keywordsList.innerHTML = this.data.items.map(item => `
<li class='keywordItem'>${item}</li>
`).join('')
this.showKeywordList()
// 4. ๋ง์ฐ์ค๋ก ์ถ์ฒ ๊ฒ์์ด๋ฅผ ๋๋ฅด๋ฉด ์ปค์๊ฐ ์์นํ ๊ฒ์์ด๊ฐ ์
๋ ฅ์ฐฝ์ ๋ฐ์๋๋ฉฐ ์ฌ์ง์ด ๊ฒ์๋ฉ๋๋ค.
this.$keywordsList.querySelectorAll('.keywordItem').forEach($item => {
$item.addEventListener('click', e => {
this.onSelectKeyword(e.target.textContent)
})
})
// 1. esc๋ฅผ ๋๋ฅด๋ฉด ์ถ์ฒ ๊ฒ์์ด ์ฐฝ์ด ๋ซํ๋๋ค.
document.addEventListener('keydown', e => {
if(e.key === 'Escape') {
this.hideKeywordList()
}
})
// 3. ๋ง์ฐ์ค๋ก ๋ค๋ฅธ ๊ณณ์ ํด๋ฆญํ์ฌ input์ด focus๋ฅผ ์์ด๋ฒ๋ฆฌ๋ ๊ฒฝ์ฐ ์ถ์ฒ ๊ฒ์์ด ์ฐฝ์ด ๋ซํ๋๋ค.
document.addEventListener('click', e => {
if(e.target.className !== 'keyword') this.hideKeywordList()
})
} else {
this.$keywordsList.innerHTML = ``
this.hideKeywordList()
}
}
}
export default Keywords
- App.js
...
this.header = new Header({ $target ...
// 4. ๋ง์ฐ์ค๋ก ์ถ์ฒ ๊ฒ์์ด๋ฅผ ๋๋ฅด๋ฉด ์ปค์๊ฐ ์์นํ ๊ฒ์์ด๊ฐ ์
๋ ฅ์ฐฝ์ ๋ฐ์๋๋ฉฐ ์ฌ์ง์ด ๊ฒ์๋ฉ๋๋ค.
this.keywords = new Keywords({ $target, onSelectKeyword: keyword => {
this.header.setState({ searchValue: keyword })
} })
...
Header ์ปดํฌ๋ํธ์ ํค์๋ ๊ฐ์ ์ ๋ฌํด ํด๋ฆญํ์ ๊ฒฝ์ฐ, input value ๊ฐ์ ํค์๋ ๊ฐ์ผ๋ก ๋ณ๊ฒฝํ๊ณ value ๊ฐ์ผ๋ก ์กฐํํ๋๋ก ๊ตฌํํ๋ค.
๊ฒ์
๊ฒ์์ด ์ผ์ด๋๋ฉด url ๋ค์ ?q={๊ฒ์์ด}๋ฅผ ๋ถ์ ๋๋ค.
โ ๏ธ ํ์ด์ง url์ ๊ฒ์์ด๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ ํ์ด์ง์ ์ง์ ํ์๋ง์ ํด๋น ๊ฒ์์ด๋ก ๊ฒ์๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋๋ก ํฉ๋๋ค.
- App.js
constructor() {
this.header = new Header({ $target, onSearch: keyword => {
this.loading.show()
api.fetchCats(keyword).then(({ data }) => {
if(data) this.setState({
items: data
})
})
// URL queryString update
this.setSearchParams(keyword)
this.loading.hide()
},
...
}
setSearchParams ํจ์
setSearchParams(keyword) {
const url = new URL(window.location);
url.searchParams.set('q', keyword);
window.history.pushState({}, '', url);
}
ํค์๋๋ฅผ ๊ฒ์ํ ๊ฒฝ์ฐ url์ ์ฌ๋ก๋ฉ ์์ด ๋ณ๊ฒฝํด์ฃผ๋ ํจ์๋ฅผ ๊ตฌํํ๋ค.
์ ๋๋ก ํ๊ฑด์ง๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค ใ ใ
- App.js
...
// URL params
if(location.search) {
const urlSearchParams = new URLSearchParams(location.search)
const searchKeyword = urlSearchParams.get('q')
if(searchKeyword) {
this.header.setState({ searchValue: searchKeyword })
}
}
...
ํ์ด์ง ์ง์ ์ url์ ๊ฒ์์ด๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ ํด๋น ๊ฒ์์ด๋ก ๊ฒ์ํ๋ ์ฝ๋๋ฅผ ๊ตฌํํ๋ค.
๐ฉ๐ป ๊ณผ์ ํ ์คํธ ํ๊ธฐ
์ฝ๋์ ๊ธฐ๋ฅ์ด ์ ์ ์ถ๊ฐ๋๋ฉด์ ์ฝ๋๊ฐ ๋ณต์กํด์ ธ ์ข ์ด๋ ค์ ๋ค. ๐ญ
๊ทธ๋๋ [ํ์] ๋ฌธ์ ๋ ๋ค ํ์๋ค. ๊ทธ๊ฑธ๋ก ์ผ๋จ ๋ง์กฑ...
์ฃผ๋ง์ ๋ค์ ์ฐจ๊ทผ์ฐจ๊ทผ ํ์ด๋ด์ผ๊ฒ ๋ค.
์ฝ๋ฉ ํ ์คํธ ๋ฌธ์
- Lv0) ๋ฌธ์ ๊ฐ์ ์ธ๊ธฐ
๋ฌธ์ ์ค๋ช
์ํ๋ฒณ ๋์๋ฌธ์๋ก๋ง ์ด๋ฃจ์ด์ง ๋ฌธ์์ด my_string์ด ์ฃผ์ด์ง ๋, my_string์์ 'A'์ ๊ฐ์, my_string์์ 'B'์ ๊ฐ์,..., my_string์์ 'Z'์ ๊ฐ์, my_string์์ 'a'์ ๊ฐ์, my_string์์ 'b'์ ๊ฐ์,..., my_string์์ 'z'์ ๊ฐ์๋ฅผ ์์๋๋ก ๋ด์ ๊ธธ์ด 52์ ์ ์ ๋ฐฐ์ด์ return ํ๋ solution ํจ์๋ฅผ ์์ฑํด ์ฃผ์ธ์.
์ ํ์ฌํญ
โ ๏ธ 1 ≤ my_string์ ๊ธธ์ด ≤ 1,000
์ ์ถ๋ ฅ ์
my_string: "Programmers"
result: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0]
๋ด๊ฐ ํผ ์ฝ๋
function solution(my_string) {
let answer = []
const upperStr = new Array(26).fill(0)
const lowerStr = new Array(26).fill(0)
const MY_STR_LEN = my_string.length
// A-Z: 65-90 (26๊ฐ), a-z: 97-122 (26๊ฐ)
for(let i=0; i<MY_STR_LEN; i++) {
const code = my_string[i].charCodeAt()
code <= 90 ? upperStr[code-65]++ : lowerStr[code-97]++
}
answer = [...upperStr, ...lowerStr]
return answer
}
๋ฌธ์๋ฅผ ์์คํค ์ฝ๋๋ก ๋ณํํ๋ charCodeAt() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ํ์ด๋ณด์๋ค.
A-Z๊น์ง 65-90์ด๊ณ , a-z๋ 97-122๋ผ์ ์ซ์๊ฐ ์ญ ์ด์ด์ ธ ๋์ด๋๋ค๋ฉด ๋ฐ๋ก ์ธ๋ฑ์ค ์ฐพ์์ ๋ฃ์์ํ ๋ฐ.. 91-96์ด ๋น์ด์ ใ ์๋ฌธ์์ธ์ง ๋๋ฌธ์์ธ์ง ์ฐพ์์ ๋ฐ๋ก ๋ฃ์ด์ฃผ๋ ์์ ์ด ํ์ํด ๋ฐฐ์ด์ ๋๊ฐ ์์ฑํ๋ค.
๋ณํํ ์ฝ๋๊ฐ์ด 90์ดํ๋ฉด ๋๋ฌธ์์ code-65ํ ๋ฐฐ์ด index๋ฅผ ์ฐพ์์ +1ํ๊ณ ์๋ฌธ์๋ฉด code-97ํ ๋ฐฐ์ด index๋ฅผ ์ฐพ์ +1์ ํด์คฌ๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ ...์ฐ์ฐ์๋ก ๋ ๋ฐฐ์ด์ ํฉ์ณ์ ๋ฆฌํดํด์ฃผ์๋ค.
- Lv0) ์ด์ด ๋ถ์ธ ์
๋ฌธ์ ์ค๋ช
์ ์๊ฐ ๋ด๊ธด ๋ฆฌ์คํธ num_list๊ฐ ์ฃผ์ด์ง๋๋ค. num_list์ ํ์๋ง ์์๋๋ก ์ด์ด ๋ถ์ธ ์์ ์ง์๋ง ์์๋๋ก ์ด์ด ๋ถ์ธ ์์ ํฉ์ returnํ๋๋ก solution ํจ์๋ฅผ ์์ฑํด์ฃผ์ธ์.
์ ํ์ฌํญ
โ ๏ธ 2 ≤ num_list์ ๊ธธ์ด ≤ 10
โ ๏ธ 1 ≤ num_list์ ์์ ≤ 9
โ ๏ธ num_list์๋ ์ ์ด๋ ํ ๊ฐ์ฉ์ ์ง์์ ํ์๊ฐ ์์ต๋๋ค.
์ ์ถ๋ ฅ ์
#1. num_list: [3, 4, 5, 2, 1] / result: 393
#2. num_list: [5, 7, 8, 3] / result: 581
๋ด๊ฐ ํผ ์ฝ๋
function solution(num_list) {
let answer = 0
let even = ''
let odd = ''
num_list.forEach(num => {
num%2 ? even += num.toString() : odd += num.toString()
})
answer = Number(even) + Number(odd)
return answer
}
num_list๋ฅผ ์ํํ๋ฉด์ ์ง์์ธ์ง ํ์์ธ์ง ํ๋จํ ํ, ์ง์๋ฉด ์ซ์๊ฐ์ even์ ๋ฌธ์์ด๋ก ์ด์ด ๋ถ์ฌ์ฃผ๊ณ ํ์๋ฉด odd์ ์ด์ด ๋ถ์ฌ์คฌ๋ค.
๊ทธ๋ฆฌ๊ณ even๊ณผ odd์ ๊ฐ์ Number๋ก ๋ณํํ ํ ๋ํด์ฃผ์๋ค.
- Lv1) ํฌ๊ธฐ๊ฐ ์์ ๋ถ๋ถ ๋ฌธ์์ด
๋ฌธ์ ์ค๋ช
์ซ์๋ก ์ด๋ฃจ์ด์ง ๋ฌธ์์ด t์ p๊ฐ ์ฃผ์ด์ง ๋, t์์ p์ ๊ธธ์ด๊ฐ ๊ฐ์ ๋ถ๋ถ๋ฌธ์์ด ์ค์์, ์ด ๋ถ๋ถ๋ฌธ์์ด์ด ๋ํ๋ด๋ ์๊ฐ p๊ฐ ๋ํ๋ด๋ ์๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ๊ฒ์ด ๋์ค๋ ํ์๋ฅผ returnํ๋ ํจ์ solution์ ์์ฑํ์ธ์.
์๋ฅผ ๋ค์ด, t="3141592"์ด๊ณ p="271" ์ธ ๊ฒฝ์ฐ, t์ ๊ธธ์ด๊ฐ 3์ธ ๋ถ๋ถ ๋ฌธ์์ด์ 314, 141, 415, 159, 592์ ๋๋ค. ์ด ๋ฌธ์์ด์ด ๋ํ๋ด๋ ์ ์ค 271๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ์๋ 141, 159 2๊ฐ ์ ๋๋ค.
์ ํ์ฌํญ
โ ๏ธ 1 ≤ p์ ๊ธธ์ด ≤ 18
โ ๏ธ p์ ๊ธธ์ด ≤ t์ ๊ธธ์ด ≤ 10,000
โ ๏ธ t์ p๋ ์ซ์๋ก๋ง ์ด๋ฃจ์ด์ง ๋ฌธ์์ด์ด๋ฉฐ, 0์ผ๋ก ์์ํ์ง ์์ต๋๋ค.
์ ์ถ๋ ฅ ์
#1. t: "3141592" / p: "271" / result: 2
#2. t: "500220839878" / p: "7" / result: 8
#3. t: "10203" / p: "15" / result: 3
๋ด๊ฐ ํผ ์ฝ๋
function solution(t, p) {
let answer = 0
const DIGIT = p.length
const pNum = Number(p)
for(let i=0; i<=t.length-DIGIT; i++) {
const targetNum = Number(t.slice(i, i+DIGIT))
if(targetNum <= pNum) answer++
}
return answer
}
p์ ์๋ฆฟ์๊ฐ ๊ฐ๊ฒ t๋ฅผ ์๋ผ์ผ ํ๋ ๋ฌธ์ ์ด๋ค.
t๋ฅผ ์ํํ๋ฉด์ slice๋ฅผ ์ด์ฉํด์ ์๋ฆฟ์์ ๋ง๊ฒ ์ซ์๋ฅผ ์๋ฅธ ํ p์ ๊ฐ๊ณผ ๋น๊ตํด์ p๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ์์ผ ๊ฒฝ์ฐ answer์ +1 ํด์ฃผ์๋ค.
๐ฉ๐ป ์ฝ๋ฉ ํ ์คํธ ํ๊ธฐ
์ฝ๋ฉ ํ ์คํธ๋ ๋ ๋ฒจ 1๊น์ง๋ง ํ์๋๋ฐ ๊ธฐ์กด์ ํ๋ก๊ทธ๋๋จธ์ค์์ ์ฝ๋ฉ ํ ์คํธ ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ๋ฒ ํ์ด์ 1๊น์ง ์ฝ๊ฒ ํ ์ ์๋ค.
ํ๋ก๊ทธ๋๋จธ์ค์ ๋ ๋ฒจ 2๋ฌธ์ ๋ ๋ง์ด ํ์ด๋ณด์๊ธฐ ๋๋ฌธ์ ๊ธ๋ฐฉ ํ ๊ฒ ๊ฐ๋ค. ๐
์ํผ ์ค๋๋ง์ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ฅผ ํธ๋ ์ฌ๋ฐ๊ธฐ๋ ํ๊ณ ๊พธ์คํ ํ๊ธฐ๋ก ํ์๋๋ฐ ๊ทธ๋์ ๋ชปํ์ด์.. ๋ค์ ๊พธ์คํ ํ์ด๋ณด์์ผ๊ฒ ๋ค๊ณ ์๊ฐํ๋ค.
๋ง๋ฌด๋ฆฌ
๋ด์ผ๋ถํฐ ๋ฐฉํ์ธ๋ฐ ๋ฐฉํ์ ์ ๋๋ก ์ฆ๊ธธ ์ ์์ ๊ฒ ๊ฐ๋ค.
์์ง ๋ฐ๋ฆฐ ๊ณต๋ถ๊ฐ ๋ง์ด ์๊ธฐ ๋๋ฌธ์ ใ ใ
๊ทธ๋๋ ๋คํํ ์ดํ์ ๋ฐฉํ์ ์ฃผ์ ๋์ ๋ค์์ฃผ์ ๋ค์ด๊ฐ๋ Figma ๊ฐ์ ์ ๊น์ง ๋ฐ๋ฆฐ ๊ฐ์๋ ๋ค ๋๋ผ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ด์ผ๋ ๋ ์ด์ฌํ ๋ฌ๋ฆฌ์
