TIL

Javascript 강의 1주차 && 2주차 숙제

황민도 2024. 4. 23. 11:20

 

 

1주차 과제 (1)

첫번째 과제는 p와 y를 대소문자 구분없이 같은 갯수 일 경우 true 값을 반환하는 로직이다. 

let s = "pPoooYY";
let result = s.split("");

let pcount = 0
let ycount = 0
for (let ptext in result) {
  if (ptext === "p" || "P") {
    pcount++
  } else if (ptext === "y" || "Y") {
    ycount++
  }
}
let ans = function (pcount, ycount) {
  if (pcount === ycount) {
    let pans = "true"
    return pans
  } else {
    let yans = "false"
    return yans
  }
}

console.log(ans)

 

생각이 드는 대로 위와 같이 작성 하였다.

하지만 드는 대로만 작성 하다보니 || 을 그냥 or 라고 만 인식 하여 그런지 위와 같이 단순하게 생각하고 코드를 짠것은

로직이 작동이 안되게끔 하였다.

 

let s = "pPoooYYy";
let result = s.split("");

let pcount = 0;
let ycount = 0;
for (let index in result) {
  let stext = result[index];
  if (stext === "p" || stext === "P") {
    pcount++
  } else if (stext === "y" || stext === "Y") {
    ycount++
  };
};
let ans = function (pcount, ycount) {
  return pcount === ycount ? "true" : "false";
};

console.log(ans(pcount, ycount));

위와 같이 (stext === "p" || stext === "P") 이렇게 두번을 반복하여 써줘야 했다.

그리고 in 자체는 result를 들여올때 키값이 없으면 index에 순서대로 0, 1, 2, 3... 위치가 반환되기 때문에 그 값으로

문자를 다시 let stext = result[index]; 이렇게 설정하여 가져와야 한다.

let s = "pPoooYYy";


let pcount = 0;
let ycount = 0;
for (let stext of s) {
  if (stext === "p" || stext === "P") {
    pcount++
  } else if (stext === "y" || stext === "Y") {
    ycount++
  };
};
let ans = function (pcount, ycount) {
  return pcount === ycount ? "true" : "false";
};

console.log(ans(pcount, ycount));

아직 배우진 않았지만 for (let stext of s) 이렇게 of 를 통해서 더 간략하게 로직을 짤 수 있다.  

 

 

ChatGPT를 활용하여 더 간단하게 로직을 짤 수도 있는지 실행해 보았다.

let s = "pPoooYY";

let pcount = 0, ycount = 0;

// 문자열 s를 순회하면서 p, P, y, Y 개수 세기
for (let char of s) {
  if (char.toLowerCase() === 'p') pcount++;
  if (char.toLowerCase() === 'y') ycount++;
}

// 개수를 비교하여 결과 출력
console.log(pcount === ycount ? "true" : "false");
  1. 문자 순회: for...of 루프를 사용하여 문자열 s의 각 문자에 접근합니다.
  2. 소문자 변환: char.toLowerCase()를 호출하여, 문자를 소문자로 변환하고 'p' 또는 'y'와 직접 비교합니다. 이렇게 하면 대소문자 구분 없이 문자를 확인할 수 있습니다.
  3. 조건문: 'p' 또는 'y'일 경우 각각의 카운트를 증가시킵니다.
  4. 결과 출력: console.log에서 삼항 연산자를 사용하여 pcount와 ycount를 비교하고, 같으면 "true", 다르면 "false"를 출력합니다.

이 방식은 코드의 길이를 줄이고, 가독성을 높이며, 같은 로직을 더 간결하게 표현할 수 있습니다.

 

 

다른 방식도 있는지 ChatGPT를 활용하여 실행해 보았다.

자바스크립트의 Array.prototype.reduce 메소드를 사용하여 한 줄로 개수를 세고 비교하는 코드를 작성할 수 있습니다.

 

let s = "pPoooYY";

// reduce를 사용하여 p와 y의 개수 비교
const result = [...s].reduce((acc, char) => {
  if (char.toLowerCase() === 'p') acc[0]++;
  if (char.toLowerCase() === 'y') acc[1]++;
  return acc;
}, [0, 0]);

console.log(result[0] === result[1] ? "true" : "false");

 

  1. Spread 연산자와 reduce: 문자열 s를 배열로 변환하고, reduce 메소드를 사용하여 각 문자를 순회하면서 'p'와 'y'의 개수를 누적합니다. 초기값 [0, 0]은 p와 y의 카운트를 각각 저장합니다.
  2. 소문자 변환: 각 문자를 toLowerCase() 메소드로 소문자로 변환한 후, 'p'와 'y'인 경우에 해당하는 카운터를 증가시킵니다.
  3. 결과 출력: reduce의 결과로 반환된 배열 result에서 'p'와 'y'의 개수가 저장된 result[0]과 result[1]을 비교하여 같으면 "true", 다르면 "false"를 출력합니다.

이 방식은 코드의 줄 수를 최소화하면서 주어진 문제를 해결하는 효율적인 방법을 제공합니다. 각 요소를 한 번씩만 순회하여 성능도 괜찮은 수준을 유지합니다.

 

내배캠 정답지 확인

function solution(s) {
  var result = true;
  s = s.toUpperCase();
  var num = 0;
  for (var i = 0; i < s.length; i++) {
    if (s[i] === 'P') num++; // p이면 갯수 더하기
    if (s[i] === 'Y') num--; // y이면 갯수 빼기
  }
  result = (num === 0); // p, y 갯수가 같으면 0 (p가 많으면 양수, 반대 음수)
  return result;
}

생각 못한 방법인데 잘짰다...

 

 

1주차 과제 (2)

절대값 구하는법 절댓값을 차례대로 담은 정수 배열 absolutes와 이 정수들의 부호를 차례대로 담은 불리언 배열 signs가 매개변수로 주어지고 실제 정수들의 합을 구하여 return 하여라 

 

이전에 배우지 않은 절댓값 구하는 법부터 찾아보았다. 사실 문제상 절댓값은 미포함 해도 되는 로직이라

상관이 없긴 한데 그래도 제대로 해보았다. 

 

단순하게 절대값 구하는 법은 다음과 같았다.

let number = -10;
let absoluteNumber = Math.abs(number);  // 절대값 반환
console.log(absoluteNumber);  // 출력: 10

 

 

만약 구하는 숫자가 많은 array 다면? 

let numbers = [-1, 2, -3, 4, -5];
let absoluteNumbers = numbers.map(Math.abs);
console.log(absoluteNumbers);  // 출력: [1, 2, 3, 4, 5]

 

 

함수를 사용하여 array 절대값 구하는법

let int = [12, -32, 45, 43]

let absolutes = int.map(function(num) {
  return Math.abs(num);
});

 

 

화살표 함수로 변형할시

let numbers = [-1, 2, -3, 4, -5];

// 화살표 함수로 절대값 계산
let absoluteNumbers = numbers.map(num => {
  return Math.abs(num);
});

console.log(absoluteNumbers);  // 출력: [1, 2, 3, 4, 5]
console.log(absolutes);

 

 

자 이제  반복문을 조건문을 통해 로직을 짤 시간이다.

 

내가 작성한 방법은 다음과 같다.

let int = [30, -20, 10, 40]
let absolutes = int.map(Math.abs);
let signs = int.map(num => num > 0);

function Return(absolutes, signs) {
  let re = 0
  for (let i = 0; i < absolutes.length; i++) {
    signs[i] ? re += absolutes[i] : re -= absolutes[i]
  }
  return re
};

console.log(Return(absolutes, signs))

 

signs 라는 변수에 int변수 안의 array안의 수가 0보다 크면 true를 반환하게끔 하였고

반복문은 for문을 사용하고

조건문은 삼항 연산자를 사용 하였다.

signs[i] ? re += absolutes[i] : re -= absolutes[i]

해석 : sings 라는 i번째 항목이 ture 라면?  re += absolutes[i]

 false 라면? re -= absolutes[i]

그리고 그렇게 재할당된 re변수 안 값을 return으로 반환 하였다.

 

내배캠 정답지 확인

function solution(absolutes, signs) {
  let answer = 0;
  // 두 배열 길이 같음
  for (let i = 0; i < absolutes.length; i++) {
  // 부호에 따라 +-
  signs[i] ? answer += absolutes[i] : answer -= absolutes[i]
  }
  return answer;
}

로직은 뭐 거의 같다고 볼 수 있다.

 

 

여담으로 강의를 듣는도중 궁금증이 생겨 실험을 해본 결과를 적어 보겠다. 

구조분해할당  ( destructuring  (de + structure + ing) )

/*

설명

de = not

structure = 구조

*/

 

추가적으로 구조분해할당을 했을시 해당부분만 undefind 가 뜨지만  

let user = {
  name: "abc",
  age: 30
};

let {
  name,
  age,
  birthday = "초기값"
} = user;
console.log(name);
console.log(age);
console.log(birthday);

위과 같이 초기값을 입력해 설정해 줄 수 있다.

 

let user = {
  name: "abc",
  age: 30,
  birthday: "yesterday"
};

let {
  name: o1,
  age: o2,
  birthday: o3
} = user;
console.log(o1);
console.log(o2);
console.log(o3);

위과 같이 새로운 변수에 재할당 하여 넣어줄 수 도 있다.

 

 

강의를 듣다가 여기서 의문이 들었던건 변수 재할당과 초기값을 같이 설정해주려면 어떻게 해야 할까?

바로 검색해서 만들어 본 결과 

let user = {
  name: "abc",
  age: 30,
};

let {
  name: o1,
  age: o2,
  birthday: o3 = "today"
} = user;
console.log(o1);
console.log(o2);
console.log(o3);

 

순서는 birthday: o3 = "today" 이렇게 작성하면 되었다.

차근차근 알아보는 과정이 정말 재미가 쏠쏠 하다. 

 

 

 

2주차 과제

문자열로 구성된 리스트 stings 와, 정수 n이 주어졌을때, 각문자열의 인덱스 n번째 글자를 기준으로

오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1 이면

각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다. 

(대충 오름차순 사전을 만든다는 얘기이다.)

 

let strings = ["name", "age", "game"]
let n = 1

function whatString(strings, n) {
  let array1 = []
  let array2 = []
  for (let i = 0; i < strings.length; i++) {
    let remind = strings[i][n] + strings[i]
    array1.push(remind);
  };

  array1.sort();
  for (let y = 0; y < strings.length; y++) {
    rearray = array1[y].replace(array1[y][0], "");
    array2.push(rearray)
  }

  return array2

};

console.log(whatString(strings, n))

 

이렇게 로직을 짜 보았는데  답안지를 보며 궁금한게 생겼다.

 

내배캠 정답지 확인

function solution(strings, n) {
  let result = [];
  2주차: es6, 일급객체로서의 함수, Map과 Set 14
  // 문자열 가장앞 글자 붙인 문자 배열 만들기
  for (let i = 0; i < strings.length; i++) {
    strings[i] = strings[i][n] + strings[i];
  }
  // 문자열 사전순 정렬
  strings.sort();
  // 앞글자 제거 후 리턴
  for (let j = 0; j < strings.length; j++) {
    strings[j] = strings[j].replace(strings[j][0], "");
    result.push(strings[j]);
  }
  return result;
};

여기서는 나처럼 array 안에 다시 글을 넣어주지 않고 바로 재정의를 해버렸다.

strings[i] = strings[i][n] + strings[i];  이렇게 말이다.

이게 어떻게 가능한지 튜터님께 찾아가 물어보았다.

튜터님께서는 strings 라는 배열이 들어오고 나서 바로 재정의 한다음 그 재정의된 strings를 바로 그 위치에 재할당

한다고 한다.

마치 배열 안의 모든 원소들을 재할당이 가능한 변수로 보면 된다 한다.

이 또한 객체도 마찬가지로 적용이 되며

내 생각처럼 메서드를 활용하여 수정을 하는 것은 전체를 재할당 하는게 아닌 일부 수정일때 더욱 적합하다고 한다.

 

오늘도 많은 깨달음을 얻어간다. 배울게 너무 많다...