[TIL] 코드스쿼드 코코아 1주차 - Part 2

Dico·2020년 11월 5일
2

[TIL]

목록 보기
2/13
post-thumbnail

코드스쿼드 코코아과정 1주차 TIL - Part2


Mission 2-1. 진수변환기

Mission 상세내용보기


My Code Review

전체코드보기


Mission 2-2. 배열다루기

Mission 상세내용보기


My Code Review

전체코드보기

.splice() ➡️ .replace()

[syntax]
array.splice(start, deleteCount, value, ...)

splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경합니다.

-MDN

splice()주요 특징:

  • slice() 와는 달리, splice()배열을 직접 변경
  • 배열에서 삭제된 요소들의 배열을 반환

Peer session 시간을 갖기 전, #2 배열거르기 문제를 for/while문으로 구현하는 문제에서 아래와 같이 코드를 생성했었지만,
(배열에 깊은 복사를 해서 새 배열을 만들면 해결될꺼라 믿었나보다...😂😂😂)

[변경 전]

const peoples = ["crong!@#", "honux5", "sarah#", "hea3d", "zello", "5lucas"];
const spc = /[~!@#$%^&*()_+|<>?:{}]/;

function filterId (arrayOfId) {
  const passedIds = arrayOfId.slice(); 📌📌📌//배열 깊은 복사
  let idx = 0;
  
  while (idx < arrayOfId.length) {	    
    let currentId = passedIds[idx];	       
    if (spc.test(currentId)) {	        
      passedIds.splice(idx, 1);  📌📌📌     
    }	 

    idx++;	
  }
//...(생략)
}

filterId(peoples);

코드리뷰를 하면서 splice(idx, 1) 가 해당배열의 길이를 변경하기 때문에 while문이 정상실행 되지않는 점을 알게 되었다.
따라서 원본 배열을 그대로 사용하는대신 replace(/[0-9]/g, "")로 삭제해야 할 특정문자가 위치한 곳에 빈칸을 대체했다. 이 방법은 배열의 길이에 영향을 주지 않아 마지막 요소까지 반복문을 정상적으로 실행할 수 있게 되었다!

[변경 후]

function filterId (arrayOfId) {
    let idx = 0;
    const unneededEl = []; 📌📌📌

    while (idx < arrayOfId.length) {
        let currentId = arrayOfId[idx];
        if (spc.test(currentId)) {
            unneededEl.push(arrayOfId[idx]); 📌📌📌
        }
        idx++;
    }

    for (var j = 0; j < unneededEl.length; j++) {
        arrayOfId.splice(arrayOfId.indexOf(unneededEl[j]), 1);
    } //여기서는 인덱스도 매번 변경되기 때문에 문제가 되지 않는다! 

    const answerArr = [];
    for (let value of arrayOfId){
        for(let i = 0; i < value.length; i++){
            if (nums.test(value[i])) {
                value = value.replace(/[0-9]/g, ""); 📌📌📌
                answerArr.push(value);
            }
        }
        if (!answerArr.includes(value)){
            answerArr.push(value);
        }
    }

    return answerArr;
}

그런데 여기서 추가로 드는 생각은,
splice()가 기존요소를 삭제 또는 교체하는 거라면 교체할 요소를 넣어줬으면 그대로 써도 됐을까? 🤔

//Ex.
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.length);   //6

arr.splice(2, 1, ""); 
console.log(arr);  //[1, 2, "", 4, 5, 6] 
console.log(arr.length);   //6 👌

....된다❗️
고치기 전에 splice()를 더 알아봤으면 좋았을 것을...
오늘은 splice()에 대해 확실히 배웠다 😂😂😂


spread operator(...)로 배열 복사하기

Mission 2-2 #4 배열만들기에서 최종적으로 반환하는 배열을 만들기 위해 빈 배열에 요소들을 push하는 방법을 사용했다.

let answerArr = [];
//(중간생략)
//numTypeEls는 숫자타입 요소를 filter해온 배열
 numTypeEls.forEach(function (el){
            answerArr.push(el);
        });

위 코드는 ES6 spread operator를 사용한 방법으로 대체할 수도 있다.

let answerArr = [];
answerArr = [...answerArr, ...numTypeEls];

loop를 돌며 numTypeEls배열이 새롭게 갱신될 때마다 answerArr배열에numTypeEls배열을 이어붙이는 것이다.
정확히 말하자면 두 배열을 복사해서 answerArr에 재할당을 해준다.
매 loop마다 업데이트 되는 answerArr를 console창에서 확인해보면 아래와 같이 나온다.
알아둬야할 점은, loop마다 복사가 계속 반복되기 때문에 (이미 복사가 된 부분의)불필요한 복사도 계속해서 일어나게 된다.
효용성 측면에서는 앞선 방법보다 떨어진다는 단점이 있다.

spread operator는 인자를 넘겨줄 때 쓰는 방법만 알고 있었는데 배열, 더 나아가 객체도 속성 전개로 복제할 수 있다는 걸 알고 신세계를 경험한 기분이었다 😃

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

얕은 복제(prototype 제외) 또는 객체의 병합은 이제 Object.assign() 보다 더 짧은 문법을 사용해 가능합니다.

-MDN



Peer Session

.replace()로 특정 문자열 삭제

문자열 내에서 특정 letter만을 삭제해야하는 경우,
const filteredValue = arr.replace(/[정규표현식]/g, "")와 같은 형식으로 replace()메소드를 이용해 삭제하고자 하는 letter를 빈칸으로 치환할 수 있다.

[syntax]
var newStr = str.replace(regexp|substr, newSubstr|function)

replace() 메서드는 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환합니다. 그 패턴은 문자열이나 정규식(RegExp)이 될 수 있으며, 교체 문자열은 문자열이나 모든 매치에 대해서 호출된 함수일 수 있습니다.

-MDN


require & exports 로 객체 전달받기

모듈화한 프로젝트에서 만약 다른 파일에 존재하는 객체를 가지고와서 사용하고자 할 때,
require(가져오기)exports는 이렇게 쓸 수 있다.

  1. 받을 객체가 하나일 떄

[내보내는 파일]
exports.변수명 = 내보낼객체명;

//json_tree.js파일에서 outObj객체 내보내기 
exports.outObj = dataTree;

[가져오는 파일]
require("가져올파일경로")

//json_tree.js파일의 전체정보를 inObj에 담기
const inObj = require("./json_tree");");

❗️여기서 주의할 점❗️
: 변수 inObj는 json_tree.js 파일의 전체 정보를 객체형태로 가져온다.
따라서 내보내진outObj객체에 접근하기 위해서는 outObj 를 하나의 key로 간주해 inObj.outObj로 불러와야한다.
위의 경우에는 하나의 객체를 가져오기 때문에 일반적으로 위와 같이 사용하기 보다는
const { outObj } = require("./json_tree") 의 형태로 사용된다.

  1. 받을 객체가 여러 개일 때

[내보내는 파일]
module.exports = {
객체명1,
객체명2,
...
}

//객체 o, 객체 dataTree 내보내기 
module.exports = {
    o,
    dataTree
}

[가져오는 파일]
const { 객체명1, 객체명2 } = require("가져올파일경로");

const { o, dataTree } = require("./data");

❗️여기서 주의할 점❗️
: 받는 파일에서도 동일한 변수명을 사용해야한다.
만일 const data = require("./data"); 로 하나의 변수에 전체 정보를 담는다면,
data.odata.dataTree 로 각 객체를 사용할 수 있다.

YouTube에서 export & require 더 알아보기


In addition to that...

  • 어느 정도의 삽질도 배우는 과정에서 중요하다!
    필요한 과정의 하나이니 시간낭비라고 생각하며 좌절하지 말 것.

  • 객체를 만드는 3가지 방법:
    1) ES6 class키워드 사용 (현재 패러다임)
    2) 생성자 함수 패턴, new 키워드 사용
    3) 객체 리터럴 {}

  • class키워드를 쓰는 이유는 역할을 분리하기 위해서. '응집도'를 위해서.

  • new 생성자 함수 패턴은 this를 쓰게 된다. 객체에서 메소드를 접근할 수 있도록. 다만 큰 단점이 있음. 만약에 여러 개의 인스턴스를 만들게 되면 모든 인스턴스가 같은 메소드를 각자 가지고 있어서 메모리를 많이 차지함. 그래서 나온 것이 prototype!
    메모리 사용의 단점을 극복하기 위해서 prototype이라는 속성의 키워드를 사용해 객체를 생성하는 것이 js에서 표준적인 방법이 됨.
    그렇지만 표현법이 번거롭기 때문에 ES2015에서 Classes라는 표준으로 class키워드를 만들어 OOP처럼 클래스를 좀 더 직관적으로 사용할 수 있게 했다.(= classprototype 의 차이점)

  • module vs. component
    module은 독립적인 단위/형태로 객체단위가 많다. 노드는 모듈이라는 용어를 많이 씀.
    component는 따지자면 UI에 가깝다. 결합이 되는 것들을 그렇게 부르는 경향이 있다. 예전에는 '위젯'이라는 용어를 많이 썼지만 이제는 '컴포넌트'라고 부른다. FE에서 많이 쓰임.
    단위는 다소 명확하지 않은 편. 개발자마다 다르게 생각하는 경우도 있음.

  • 정규표현식을 공부해보는 것도 좋지만 중요도는 높지 않음. 특수기호가 의미가 없다는 걸 표현하기 위해서는 이스케이프(escape; 역슬래쉬\)를 사용해야 함. "패턴"이 있을 때 정규표현식을 쓸 수 있다. (ex. 이메일 체크 등)

  • 내가 보기 위한 기술블로그를 쓰면 실력이 많이 는다!! 혼자만 볼 수 있는 블로그를 써도 괜찮다는 것. 모두가 쉽게 이해할 수 있는 설명이 아니어도 괜찮고 짧아도 괜찮음. 꿀벌개발일지(https://ohgyun.com/)참고.

  • debugging 시, 변수명을 watch에 입력하면 변수에 담긴 값을 볼 수 있다. 그리고 해당 라인에서 마우스 오른쪽 버튼을 눌러 Add conditional breakpoint로 변수가 임시로 다른 값을 할당해볼 수도 있다.

  • 설계하기(중요도: ⭐️⭐️⭐️⭐️⭐️)
    Q: 설계는 어떻게 해야할까?
    A: 코드를 짜기 전, 종이에다가 먼저 끄적거리면서 시각화를 해보는 것이다(주석을 사용할 수도 있음).
    경우의 수를 나열(일단 무조건 나열하다보면 패턴이 보일 수 있다)해보고, 공식이나 패턴을 찾아보면서 흐름을 본다.
    설계 : 코딩의 비율은 9 : 1로. 타이핑 자체를 얼마 걸리지 않는다. 즉, 타이밍 시간을 제외한 나머지 시간에는 설계를 해도 된다는 것.
    code & fix 하지말고 design & code 해라!!
    설계 ⬅️➡️ 검증
    이 과정을 꾸준히 거치면 나중에 복잡한 문제를 맞닥뜨려도 어떻게 해결해야 할 지 알게 된다. 현업의 문제는 복잡도가 올라가기 때문에 단순히 code & fix만으로는 고칠 수 없을 수 있다.
    설계를 잘 한다는 것 = design을 잘 한다는 것. design을 할 수 있어야 손코딩을 할 수 있다.

  • 프로그래밍 연습하기
    1) 시간정하기 (내 속도를 아는 것은 굉장히 중요하다)
    2) 다시 풀기 (어제 푼 문제를 또 풀어보고 얼마나 걸리는 지 재본다. 다시 짜면 저절로 더 나은 코드로 짜게 된다.)
    3) 배운 내용 정리하기

  • 학습 checkpoint 를 중심으로 학습하기

  • + 코드 작성 시 유의점
    1) 전역변수는 최소한으로. 클래스가 전역변수이기 때문에 대신 클래스를 만드는 방법도 있음.
    2) const블록스코프를 가진다.
    3) 변수명은 의미있는 이름으로 의도를 알 수 있게짓기. 값이 무엇을 의미하는 지 변수로 저장하는 게 좋다.
    4) 함수합성은 breakpoint를 걸어 확인하기가 어렵다. 값을 너무 중첩해서 표현하면 debugging에 분리하기 때문에 조금은 변수로 분리해서 표현하는 것을 추천.
    5) 같은 결과를 주는 코드를 반복적으로 작성하지는 않는지 확인하기
    6) 보는 사람이 이해가 어려운 코드는 잘 쓴 코드가 아니다. 장황하게 쓰지말 것.
    7) 한줄의 코드가 길어져서 가로로 스크롤이 생긴다면 줄바꿈이 필요.
    8) 콜백 함수나 간단한 함수는 ES6 람다표현법(화살표함수) 사용해서 표현하기

    //일반 함수 
    function replaceN (str) {
      str.replace(/[0-9]/g, '');
    }
    
    //람다표현법(ES6)
    const replaceN = (str) => str.replace(/[0-9]/g, '');
  • false가 나오는 조건들/falsy값 9가지 (이 정도는 외우기📍):
    1) 0
    2)-0
    3)false
    4)undefined
    5)null
    6)""
    7)''
    8)``(backtick)
    9)NaN

  • for ofiterable(+ iterable 더 알아보기)을 순회할 수가 있음. 문자열이나 유사배열도 가능.

  • forEach함수를 인자로 받는다는 점에서 특이하다.
    인자로 받는 함수를 배열의 요소를 인자로 전달 받을 때마다 실행시키는 것. 표현식의 향상❗️
    즉, 함수를 돌리는 함수인 것이다.
    '일급객체' 가 무엇인지 알아볼 것. 자바스크립트에서 함수는 일급객체이기 때문에 값으로 취급할 수 있는 것.
    forEach는 다른 메소드와 연속적으로 오는 Chaining 기법으로도 많이 쓰이는데, Chaining 기법같은 타입을 반환하는 것들끼리 가능하다❗️
    함수 Chaining은 Pipeline(파이프 연산자)으로 중첩 함수 호출을 좀 더 읽기 좋은 형식으로 작성할 수 있다.
    forEach는 반환하는 것이 없다.

  • mapfilter새로운 배열을 반환한다❗️

  • reduce는 동작방식이 조금 다르다. 사용법을 먼저 알아보자. 원래 처음에는 이해가 잘 안간다. 사용법이 이해가 되면 만들어보는 것. reducer은 굉장히 많이 쓰인다.
    reduce는 새로운 차원의 타입을 만든다. 타입체인지가 일어남❗️
    ex) 배열 ➡️ 문자열, 배열 ➡️ 객체, 등등...
    전혀 다른 타입의 값이 나온다.

  • 고차함수들은 함수의 이름만 받아서 값을 돌려준다. 나중에 되불려진다고 해서 '콜백'이라고 불린다. 즉시 실행되는 것이 아니라 나중에 실행된다.

  • FE자료구조의 기본은 배열 & 객체이다. 연속적인 데이터의 처리가 쉽다.

  • addEventListener는 (순서대로 실행하지 않는)비동기 함수다.

  • 실행해서 직접 바꾸면 mutable(가변), 새로운 걸 만들면 immutable(불변).
    객체와 변경불가성 (poiemaweb)
    api를 쓸 때는 구별해야 한다.


To-do List 💪

  • #객체지향프로그램 이란?
  • #일급객체 자바스크립트(first class citizen) 란?
    • 다음 조건을 만족하는 객체는 1급 객체:
      1) 변수나 데이터 구조안에 담을 수 있다.
      2) 파라미터로 전달할 수 있다.
      3) 반환값(return value)로 사용할 수 있다.
      4) 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다.
      5) 동적으로 프로퍼티 할당이 가능하다.
    • JavaScript에서 함수(Function)은 객체(Object)이므로 1급 함수로 불린다.
  • #고차함수 (High-Order Function) 란?
    • 다음 조건을 만족하는 함수는 고차 함수:
      1) 함수에 함수를 파라미터로 전달할 수 있다.
      2) 함수의 반환값으로 함수를 사용할 수 있다.
    • 고차함수는 1급 함수부분집합(Subset)이다.
  • #순수 함수 (Pure Function) 란?
    • 순수 함수란 함수형 프로그래밍에 필요한 개념으로 아래 조건을 만족하는 함수:
      1) 동일한 입력에는 항상 같은 값을 반환해야 한다.
      2) 함수의 실행은 프로그램의 실행에 영향을 미치지 않아야 한다.(side effect가 없어야 함. 예를 들어 함수 내부에서 인자의 값을 변경하거나 프로그램의 상태를 변경하는 행위)
    • 순수 함수를 호출하면 프로그램의 어떠한 변화도 없고, 입력 값에 대한 결과를 예측할 수 있어서 테스트하기가 쉽다.
  • #big o notation 이란?
    • 시간 복잡도를 쉽게 소통할 목적으로 자료 구조와 알고리즘의 효율성을 간결하고 일관된 언어로 설명하기 위해 수학적 개념을 차용한 것. Big O는 시간 단위가 아닌 알고리즘에 필요한 단계 수만을 고려함으로써 일관성을 유지한다.
    • O(1) : 상수시간; constant time; 데이터의 수와는 상관없이 항상 걸리는 단계 수가 일정한 알고리즘. ("빅 오 1"/"차수 1"/"오 1" 등으로 읽는다.)
    • O(log N) : 로가리즘; logarithm; 데이터가 두 배로 증가할 때마다 한 단계씩 늘어나는 이진 검색의 알고리즘.
    • O(N) : 선형시간; linear time; 데이터가 하나씩 추가될 때마다 한 단계씩 늘어나는 알고리즘.
  • #spread operator 란?
  • forEach, map, filter, reduce관련 내용 정리하기

Reference 📚

*본 포스팅은 아래 사이트들을 참고 및 인용하여 작성되었습니다.
학습단계로 잘못된 정보가 있을 수 있습니다. 잘못된 부분에 대해 알려주시면 곧바로 정정하도록 하겠습니다 😊
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/replace
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
https://ohgyun.com/
https://blittle.github.io/chrome-dev-tools/sources/debugging.html
https://poiemaweb.com/js-object-oriented-programming
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Spread_syntax
https://poiemaweb.com/es6-iteration-for-of
https://poiemaweb.com/js-immutability
https://krksap.tistory.com/830
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Pipeline_operator
https://velog.io/@kyusung/%ED%95%A8%EC%88%98%ED%98%95-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9A%94%EC%95%BD

profile
프린이의 코묻은 코드가 쌓이는 공간

2개의 댓글

comment-user-thumbnail
2020년 11월 9일

디코 최고예요 👍🏻

1개의 답글