회고

[취업준비일지] - 110

Happy Programmer 2023. 2. 7. 23:48

1.배열의 값을 변동시키면서 기존 데이터와 다른 주소값을 부여하고 싶다면(깊은 복사)
일반적으로는 구조분해 할당을 사용했다.

배열을 그대로 이동시킨 다음 배열을 수정할 경우
아래와 같이 arr까지 변경되는 모습을 볼 수 있다.

let arr = [1,2,3]
let arr2 = arr
arr2.push(4)
console.log(arr) => [1,2,3,4]

 

 

하지만 구조분해할당을 사용해 새로 추가하거나
내부 값을 직접 변경할 경우에는 새로운 배열에 값을 추가하는 것이기 때문에
기존과 다른 주소에 할당되어 기존 arr은 변경되지 않는 것을 볼 수 있었는데

let arr = [1,2,3]
let arr2 = [...arr]
arr2.push(4)
console.log(arr) => [1,2,3]

let arr = [1,2,3]
let arr2 = []
arr.forEach(el => arr2.push(el))
arr2.push(4)
console.log(arr) => [1,2,3]

 

 

이와 유사하게 concat을 사용하면 새로운 주소값이 할당되는 모습을 볼 수 있었다.

let arr = [1,2,3]
let arr2 = arr.concat([])
arr2.push(4)
console.log(arr,arr2)  => [1,2,3],  => [1,2,3,4]


이전에는 concat은 단순 통합이라고만 생각했고
구조분해할당이 익숙했기 때문에 사용하지 않았는데
concat에 빈배열만 담더라도 새로운 배열 안에서 
arr과 담긴 배열(여기선 빈배열)의 내용이 합쳐지는 것을 알 수 있었다.


2.CRUD의 update를 할 때 딱히 고민하지 않고
axios의 PUT 또는 PATCH를 큰 구별없이 사용했는데
이런 방식을 사용하기 때문에 간단하게 id만 특정해 보내주면
배열의 관리와는 상관없이 값을 수정해주는 것을 볼 수 있다.
(PUT과 PATCH는 3번에서)

하지만 axios등을 사용하기 전 로컬에서 데이터를 다룰 때는
직접적으로 배열을 관리해줘야 했는데
내부 값의 수정이 서버 통신을 할 때 보다 복잡함을 느꼈었다.

물론 작년 6월달 시점에서 서버 통신으로 넘어가 잊혀진 주제지만
그 당시에는 id값의 위치를 특정하고 그 id값의 객체를 분리한 다음
그 객체의 앞과 뒤를 잘라서 보관하고
최종적으로 배열 내부에서 구조분해할당으로 처리했다.


[...앞배열, 수정객체, ...뒷배열]의 복잡한 방식이지만
그 당시에는 구현했다는 것 만으로도 뿌듯해하며 지나갔었는데

let datas = [{id:1, data:"aaa"},{id:2, data:"bbb"},{id:3, data:"ccc"}]
let editnum = 2

const newData = [...datas].filter((e) => {
return editnum === e.id;
})[0];
const beforeData = [...datas].filter((e) => {
return editnum > e.id;
});
const nextData = [...datas].filter((e) => {
return editnum < e.id;
});

updatedDatas = [
  ...beforeData,
  {
    id: editnum,
    data: "changed"
  },
  ...nextData,
]

console.log(updatedDatas)
// [0: {id: 1, data: 'aaa'}
//  1: {id: 2, data: 'changed'}
//  2: {id: 3, data: 'ccc'}
// ]


사실 map을 쓰면 간단하게 문제가 해결되는 것을 볼 수 있다.

let datas = [{id:1, data:"aaa"},{id:2, data:"bbb"},{id:3, data:"ccc"}]
let editnum = 2

const newData = datas.map(el => {
    if(el.id === editnum){
        return{
            id:2,
            data:"changed"
        }
    }
    return el
})
console.log(newData)
// [0: {id: 1, data: 'aaa'}
//  1: {id: 2, data: 'changed'}
//  2: {id: 3, data: 'ccc'}
// ]


또는 삼항연산자를 통해 쉽게 조건에 따른 결과 retune을 할 수도 있다.

newData = datas.map(el => el.id === editnum ? {...el, el.data : "changed"} : el)

 

 

배열 사이에 있는 객체 내부 데이터를 수정할 경우 map을 사용해 간단하게 변경할 수 있으니
update를 처음 시도할 때는 겁먹지 말고 map을 사용하자


3.PUT과 PATCH 모두 update의 기능이 있다고만 알고 사용했기 때문에
극 초반에 차이점을 듣기는 했지만 잊고 있었는데
이번 update 기능을 확인하며 put과 patch가 떠올라 무슨 차이가 있는지 알아봤다.

하나의 데이터 객체가 존재할 때 people = {id:1, name:"지창", job:null}
PUT을 사용할 경우 PUT/people/1 {job:"프론트엔드 개발자"}
이름이 날아가버리는 모습을 볼 수 있다. {id:1, job:"프론트엔드 개발자"}

하지만 같은 데이터에 PATCH를 사용할 경우 PATCH/people/1 {job:"프론트엔드 개발자"}
job의 부분만 변경되는 모습을 볼 수 있다. {id:1, name:"지창", job:"프론트엔드 개발자"}

둘의 차이는 전체를 날려버리고 새로운 객체를 넣어주느냐(id 기준이라 배열 내 index등은 그대로다)
아니면 특정 부분의 정보만 변경하느냐의 차이로
PUT은 구조분해할당처럼 새로운 객체가 되어버리는 것이고
PATCH는 조심스럽게 접근해서 값 하나만 수정한다고 볼 수 있다.

PUT은 (통채로)놓다, PATCH는 조각이라는 느낌으로 구별하면 기억하기 쉬운 것 같다.




(1).백준 2231 분해합은 이전에 풀었던 셀프넘버와 뭔가 유사한 느낌의 문제였다.
한 숫자의 분해합을 그 숫자+각 자릿수라고 할 때(245 = 245+2+4+5 => 256)
245는 256을 만들어 245의 분해합은 256이고, 256의 생성자는 245라고 부르는 식이다.

주어진 숫자의 분해합 중 가장 작은 숫자를 구하라는 문제였는데
간단하게는 1부터 목표 숫자 이전까지만 체크를 하면 되는 것이고

그 처리를 하는 함수는 투입된 숫자를 result에 저장한 다음 
10으로 나눈 나머지를 계속해서 더해 분해합을 만들어 준 후
분해합이 현재 목표한 분해합과 같은지를 boolean으로 리턴하게 만들었다.

만약 결과가 true라면 0으로 설정된 결과값을 현재 i값(시도한 값)으로 교체하고
break를 통해 결과를 출력하는 방식이며

끝까지 true가 출력되지 않는다면(분해합이 일치하지 않으면)
기존에 설정된 0이 출력되는 방식으로 해결했다.

let input = 216

let result = 0
const makerCheck = (num) => {
    let result = num
    while(num){
       result += num%10
        num = Math.floor(num/10)
    }
    if(result === input) return true
    else return false
}

for(let i = 1 ; i <= input ; i++){
    if(makerCheck(i)){
        result = i
        break
    }
}

console.log(result)


여기서 최적화 할 방법에 대해 생각해본다면
각 자릿수당 추가될 수 있는 숫자는 9이기 때문에
150을 만들 수 있는 최저 숫자는 x + x1 + x2 + x3가 될 것이고
가능한 최소 숫자 또한 27을 뺀 123부터가 될 것이다.
그러한 방식으로 자릿수를 체크해 각 자릿수의 개수마다 9씩 차감한 숫자부터 시작한다면
100억이라는 숫자를 1부터 올라갈 수는 없지만
99억9999만9910부터 시작해서 90개를 체크하는 것은 무리가 없을 것이다.

하지만 체크하는 숫자는 겨우 100만개이기 때문에
바로 문제가 해결되는 것을 보고 개선을 적용하지는 않았고
생각해보니 낮은 자릿수의 경우 터져버릴수 있기 때문에
(2의 경우 생성자는 1이지만 자릿수가 1개이기 때문에 -9를 적용한 -7부터 확인하게 되고
이는 말이 되지 않기 때문에 Math.max(1,x)를 통해
시작 최소값은 1이 되도록 만들어야한다.