전체 단어에서 각 문자는 공백으로 나누어져 있고 ‘Z’ 라는 글자가 있으면 ‘Z’라는 글자 포함해서 그 앞에 있는 글자까지 제거하고 난 뒤 남아 있는 숫자를 누적해서 더하는 알고리즘 문제다.
일단 1시간 정도 고민해서 내가 접근해 본 방법은 아래와 같다.
function solution(s) {
const result = s.split(' ')
console.log(result)
const arr = []
for (let i = 0; i < result.length; i++) {
if (result[i] === 'Z') {
if (result[i - 2] !== 'Z') {
arr.push(result[i - 2])
}
} else {
if (result[i + 1] !== 'Z') {
arr.push(result[i])
}
}
}
const filteredArray = arr.filter(
(item) => item !== undefined && item !== null
)
return [...new Set(filteredArray)].reduce(
(acc, cur) => Number(acc) + Number(cur),
0
)
}
일단 문자열을 공백으로 나눠서 배열에 담고 배열을 돌면서 ‘Z’라는 글자를 찾은 다음 ‘Z’글자의 앞에 앞에 있는 글자를 찾아서 새로운 배열에 추가하고 숫자의 그 다음 글자가 Z가 아니면 그 글자를 추가하도록 구현해봤지만 역시나 오늘도 3개의 테스트는 통과했지만, 제출하고 나서 나머지 테스트는 통과하지 못했다. 예외사항이 존재하는 것 같다. 일단은 0 ~ 1단계 수준은 1시간 정도 고민하고 안 풀리면 다른 사람들의 풀이를 보고 이해하는 방식으로 자주자주 알고리즘을 접하는 방식으로 진행하기로 정했기 때문에, 오늘도 1시간 지나자마자 구글링해서 다른 사람들의 풀이를 확인했다.
function solution(s) {
s = s.split(' ')
while (s.includes('Z')) {
s.splice(s.indexOf('Z') - 1, 2)
}
return s.reduce((a, b) => a + Number(b), 0)
}
와… 근데 정말 놀랍다. 이 사람이 이걸 한 번에 생각해 낸 걸까? 너무나 간단하게 해결해서 대단하다는 생각밖에 안 든다. 하지만 어쨌든 감탄하는데서 멈추지 말고 이 코드를 제대로 이해하고 나중에 써먹을 수 있도록 해야 한다.
그리고 이쯤에서 드는 생각인데, 0단계 100문제를 모두 풀었다고 해서 그냥 바로 1단계로 넘어갈 게 아니라 0단계에 있는 알고리즘을 잘 활용줄 알아야 되지 않나라는 생각이 든다.
하지만 이건 그때 가서 생각해보고 일단은 100문제부터 해결하는 게 우선이다.
import AlexaImage from './images/alexa.png'
function App() {
return (
<div>
<img src={AlexaImage} alt="" />
<p>hello image</p>
</div>
)
}
export default App
AlexaImage 같이 대문자로 명명하는 게 보통의 컨벤션이다. 이 이미지 말고 다른 이미지도 가지고 와서 console에 찍어보면 두 개의 이미지가 다른 방식으로 출력을 하고 있다는 걸 알 수 있다.
import AlexaImage from './images/alexa.png'
import SiriImage from './images/siri.png'
console.log(AlexaImage)
console.log(SiriImage)
function App() {
return (
<div>
<img src={AlexaImage} alt="" />
<img src={SiriImage} alt="" />
<p>hello image</p>
</div>
)
}
export default App
이미지가 9.7KB 보다 크면 이미지를 압축해서 파일명으로 보여주고 그렇지 않으면 base64로 인코딩해서 보여준다.
<img src={AlexaImage} alt="" width={500} height={500} />
<img src={SiriImage} alt="" style={{ width: 500, height: 500 }} />
에러에는 컴파일 에러와 런타임 에러가 있다.
컴파일 에러는 컴파일을 할 때 발생하는 에러고 런타임 에러는 컴파일 이후에 실행하는 과정에서 발생하는 에러다.
소스코드에 debugger를 입력해서 디버깅하거나 개발자도구에서 중단점을 찍어서 할 수 있다. 리액트의 경우 리액트 devTools와 Profiler로도 디버깅이 가능하다.
기존에 숫자 정렬은 아래 코드와 같이 어느 정도 알고 있었다.
const arr = [1, 2, 10, 3]
arr.sort()
console.log(arr) // [(1, 10, 2, 3)]
arr.sort((a, b) => a - b)
console.log(arr) // [(1, 2, 3, 10)]
하지만 문자열 정렬에 대해서는 크게 고민해보지 않았는데, 이번에 강의 들으면서 추가로 알게 된 내용이니 이참에 정리해보자.
문자열을 그냥 정렬하게 되면, 소문자와 대문자의 아스키 코드의 숫자값 때문에 내가 원하는 대로 정렬이 되지 않을 수도 있다.
아래와 같은 배열이 있다고 할 때 소문자와 대문자가 같이 정렬되기를 바란다고 가정해보자.
const strArr = ['a', 'b', 'A', 'B', 't']
strArr.sort()
이렇게 정렬하게 되면 아래와 같이 정렬된다. 이는 아스키 코드 값을 기준으로 정렬했기 때문이다.
console.log(strArr) // [ 'A', 'B', 'a', 'b', 't' ]
이때 localeCompare를 이용해서 소문자와 대문자를 고려하면서 문자열을 정렬할 수 있다.
strArr.sort((a, b) => a.localeCompare(b))
console.log(strArr) // [ 'a', 'A', 'b', 'B', 't' ]
그렇다면 여러가지 속성을 가지고 있는 객체를 정렬하려면 어떻게 해야할까?
const vegitables = [
{ weight: 10, cost: 10, name: '양파' },
{ weight: 5, cost: 20, name: '토마토' },
{ weight: 20, cost: 5, name: '당근' }
]
이런 객체가 있다고 했을때, weight, cost별로 정렬해보자.
const vegitables = [
{ weight: 10, cost: 10, name: '양파' },
{ weight: 5, cost: 20, name: '토마토' },
{ weight: 20, cost: 5, name: '당근' }
]
const sortWeightVegitables = [...vegitables]
sortWeightVegitables.sort((a, b) => a.weight - b.weight)
console.log(sortWeightVegitables)
console.log(vegitables)
const sortCostVegitables = [...vegitables]
sortCostVegitables.sort((a, b) => b.cost - a.cost)
console.log(sortCostVegitables)
일단 sort메서드는 기존 배열자체를 수정해서 정렬하기 때문에 기존 배열을 스프레드해서 새로운 배열을 선언했다. 그렇게 하고 정렬하고 싶은 배열 안에 있는 하나하나의 객체를 a,b로 생각해보자면 a,b의 정렬하고 싶은 속성을 a.weight - b.weight와 같이 선언하면서 원하는 정렬 방식을 선택하면 된다.
그리고 객체의 속성이 소문자, 대문자가 섞어 있는 경우에도 localeCompare를 사용해서 정렬할 수 있다.
const CharacterItem = [
{ weight: 10, cost: 10, name: 'A' },
{ weight: 5, cost: 20, name: 'a' },
{ weight: 20, cost: 5, name: 'c' },
{ weight: 20, cost: 5, name: 'b' },
{ weight: 20, cost: 5, name: 'B' },
{ weight: 20, cost: 5, name: 'C' }
]
const sortCharacterItem = [...CharacterItem]
sortCharacterItem.sort((a, b) => a.name.localeCompare(b.name))
console.log('sortCharacterItem', sortCharacterItem) //
/*
소문자 대문자 고려해서 정렬됨
sortCharacterItem [
{ weight: 5, cost: 20, name: 'a' },
{ weight: 10, cost: 10, name: 'A' },
{ weight: 20, cost: 5, name: 'b' },
{ weight: 20, cost: 5, name: 'B' },
{ weight: 20, cost: 5, name: 'c' },
{ weight: 20, cost: 5, name: 'C' }
]
*/
Re-evaluating 과 re-rendering은 완전히 동일한 개념이 아니다.
함수 컴포넌트가 재평가 된다고 해서 반드시 리렌더링이 일어나는 것이 아니다. 재실행되는 것은 컴포넌트이고 리렌더링되는 건 DOM이기 때문이다.