23/11/22

Laejun Kim·2023년 11월 22일
1

TIL

목록 보기
41/89
post-thumbnail

연습문제

3진법 뒤집기

출처) https://school.programmers.co.kr/learn/courses/30/lessons/68935

  • 자연수 n이 매개변수로 주어집니다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한 수를 return 하도록 solution 함수를 완성해주세요.

<내 풀이>

function solution(n) {
   let temp=n.toString(3)+''
   let temp2 = temp.split('').reverse()
   let temp3 = temp2.join('')
   return parseInt(temp3,3)
}
  1. 제공받은 숫자 n을 3진법으로 바꿈과 동시에 string으로 변환하여 temp에 저장.
  2. temp의 숫자들을 각각 쪼개서 배열에 넣으면서 reverse()를 이용하여 순서 역전하여 temp2 에 저장
  3. temp2의 배열을 join()으로 하나의 문자열로 바꾼 뒤 마지막으로 parseInt()를 이용하여 10진법 정수로 변환

<배운 점>

toString 과 parseInt의 완전히 새로운 사용법을 배웠다.

  • toString() 의 인자로 숫자를 전달하면 해당 숫자에 해당하는 진법의 숫자로 바꿔준다.
    예를 들어 n=100 인 상황에서 n.toString(2)라고 적게 되면 100을 2진법으로 바꾼 string인 '1100100'이 리턴된다.
  • parseInt()의 두번째 인자로 숫자 x를 전달하면 그건 첫번째 인자로 전달한 것이 x진법으로 적혀있다는 의미가 된다.
    예를 들어 parseInt(n,3) 이라면
    "3진법으로 적힌 숫자 n을 10진법 정수로 바꿔줘"
    라는 요청이 된다

직사각형 별 찍기

출처) https://school.programmers.co.kr/learn/courses/30/lessons/12969

  • 이 문제에는 표준 입력으로 두 개의 정수 n과 m이 주어집니다.
    별(*) 문자를 이용해 가로의 길이가 n, 세로의 길이가 m인 직사각형 형태를 출력해보세요.

<내 풀이>

process.stdin.setEncoding('utf8');
process.stdin.on('data', data => {
    const n = data.split(" ");
    const a = Number(n[0]), b = Number(n[1]);
    // console.log(a);
    // console.log(b);
    let htemp= "*".repeat(a)
    let vtemp= `${htemp}\n`
    console.log(vtemp.repeat(b))
});
  1. 별을 a개 만큼 반복한 문자열로 가로를 구성하고
  2. b개 만큼 해당 가로열을 반복한다.
  3. 이때 줄바꿈은 각 가로열의 끝에서 \n을 이용한다.

<배운 점>

  • 템플릿 리터럴 안에서 줄바꿈이 잘 안되는 경우가 많았는데 \n을 사용하는 것도 방법이 될 수 있다. n은 new line 의 약자라고 한다.

뉴스피드 팀 프로젝트

problem

Detail 페이지로 넘어갈때 해당 피드의 정보를 불러들이는 문제

<상황 파악>

페이지 구성 자체는 지난번 프로젝트와 유사하다. Home 페이지에서 여러 피드들을 한번에 확인할 수 있고, 각 피드를 클릭하면 해당 피드의 상세를 확인할 수 있는 Detail 페이지로 넘어가는 방식이다.

어렵지 않게 구현 가능할 것으로 생각했으나 막상 시도해 보니 예상치 못한 문제에 직면했다.

피드의 id를 주소창으로 넘기고 이를 useParams를 이용하여 다시 받아오는 것 까지는 문제 없었는데 getDocs로 해당 id를 가진 피드를 불러들이는데 실패한 것이다.

원인을 찾아보니 firebase에서 사용하는 데이터베이스의 데이터 구조 자체가 원인이었다.

위가 데이터의 형태인데, 피드의 id로 사용한 것은 문서id(doc.id)인 반면 그 문서 내부에는 id필드가 존재하지 않는다.

즉 , 콜렉션 전체를 가져오고 필드를 기준으로 필터링 해오던 기존의 방식을 사용할수 없는 상황.

<문제 해결>

디테일 페이지로 넘어갈때 피드 아이디를 넘기는 것은 그대로 유지하면서 firebase에서 데이터를 가져올때 컬렉션 전체를 가져오는 것이 아닌 특정 id를 가진 문서만을 가져오도록 코드를 다시 짰다.

//before
import { collection, getDocs, query, where } from 'firebase/firestore';
//after
import { doc, getDoc } from 'firebase/firestore';

콜렉션을 가져오는 것이 아니라 문서 하나를 가져오는 것이니 collection 대신 doc을, 여러 문서를 가져오는 것이 아닌 문서 하나를 가져오는 것이니 getDocs대신 getDoc 을, 그리고 필터링 할 필요가 없으므로 query와 where는 사용하지 않게 되었다.

실제로 데이터를 가져오는 함수는 아래와 같다

 const fetchData = async () => {
      const feedRef = doc(db, 'feeds', params.id);
      const docSnapshot = await getDoc(feedRef);
      const initialFeed = { ...docSnapshot.data() };
      setFeed(initialFeed);
    };
    fetchData();
  }, []);

feedRef 에서 params.id를 적어준 부분이 중요하다. 이를 통해 가져오고자 하는 id를 가진 문서를 정확하게 하나만 가져올 수 있다. 어차피 하나만 가져오는 것이니 where()를 사용한 로직은 필요하지 않다. 이후에는 jsx 문에서 feed state에 저장된 정보를 하나씩 꺼내서 화면에 필요에 따라 뿌려주면 된다.

참고) https://mingeesuh.tistory.com/entry/Firebase-%ED%8C%8C%EC%9D%B4%EC%96%B4%EC%8A%A4%ED%86%A0%EC%96%B4%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B6%88%EB%9F%AC%EC%98%A4%EA%B3%A0-%EC%93%B0%EA%B8%B0-feat-React

0개의 댓글