DEVELOP

01. 배열 메소드Ⅰ. forEach와 map

# 콜백함수 (CallBack Function)

: 다른 함수가 실행을 끝낸 뒤 실행되는 callback되는 함수

 

 

# forEach 함수 

(method) Array<number>.forEach(callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any): void

: 배열의 요소를 하나씩 살펴보면서 반복 작업을 하는 메소드 

- 리턴 값이 없다. (undefined)

- array 요소들을 제공된 함수로 한 번 실행 

- 기존 배열 변경 가능

- 최대 반복 횟수는 최초 호출 시 요소의 개수 

const numbers = [1,2,3,4];

numbers.forEach((x, i, arr)=>{
  numbers[i] = x **2 ;
})

console.log(numbers); // [1,4,9,16]

# Map함수 

(method) Array<number>.map<number>(callbackfn: (value: number, index: number, array: number[]) => number, thisArg?: any): number[]

- 새로운 배열을 반환 

- 기존의 배열을 이용해 새로운 배열 가공 시 사용 

- 기존 배열 변경x 

-  최대 반복 횟수는 최초 호출 시 요소의 개수 

const numbers = [1,2,3,4];

const newNumbers = numbers.map((x,i,arr)=>{
  return x*3;
})

console.log(newNumbers); // [3,12,27,48]
console.log(numbers); // [1,4,9,16]

02. 할 일 정리

const list = document.querySelector('.list');
const data = [{
    title: '자바스크립트 공부하기',
    isClear: true,
  }, {
    title: '쓰레기 분리수거',
    isClear: false,
  }, {
    title: '고양이 밥주기',
    isClear: true,
  }, {
    title: '독서하기',
    isClear: false,
  }, {
    title: '영어 공부하기',
    isClear: false,
  }
];

data.forEach((todo,i) =>{
  const li = document.createElement('li');

  if(todo.isClear){
    li.classList.add('item','done');
  }else{
    li.classList.add('item');
  }

  li.textContent = `${i+1}. ${todo.title}`;
  list.appendChild(li);
});

# querySelector

: 특정 name,id,class를 제한하지 않고 css선택자를 사용하여 요소를 찾는다.

- 같은 id 또는 class 일 경우 스크립트의 최상단 요소만 로직에 포함

querySelector(#id) => id 값 id를 가진 요소를 찾기

querySelector(.class) => class값 class를 가진 요소를 찾기 

# createElement

: 지정한 tagName의 HTML 요소를 만들어 반환

 

# classList.add 

: 해당 요소의 클래스 속성값을 추가, 같은 클래스명 있는 경우 무시

 

# appendChild

: 선택한 요소 안에 자식요소를 추가

* {
    box-sizing: border-box;
  }
  
  body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      padding: 0;
      background-image: url('imgs/background.jpg');
      background-size: cover;
      background-repeat: no-repeat;
  }
  
  body::after {
      display: block;
      content: '';
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      background-color: #2d2b2a;
      opacity: .4;
      z-index: -1;
  }
  
  .main {
      width: 360px;
      min-height: 350px;
      margin: 40px;
    padding: 20px 0;
    background-color: rgba(255, 255, 255, 0.95);
    box-shadow: 0px 0px 15px #333333;
    border-radius: 8px;
    text-align: center;
  }
  
  .title {
      margin: 10px auto 25px;
      font-size: 30px;
      font-weight: 600;
      color: #000000;
  }
  
  .add-container {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 260px;
      height: 27px;
      margin: 0 auto;
      border: 1px solid #333333;
      border-radius: 10px;
      overflow: hidden;
  }
  
  .add-input {
      width: 80%;
      height: 27px;
      padding: 0 10px;
      border: none;
  }
  
  .add-btn {
      width: 20%;
      height: 27px;
      color: #FFFFFF;
      border: none;
      border-left: 1px solid #333333;
      background-color: #876237;
      cursor: pointer;
  }
  
  .list {
    width: 260px;
      margin: 18px auto;
      padding: 0;
      list-style: none;
  }
  
  .item {
      display: flex;
      align-items: center;
      width: 100%;
      height: 40px;
      margin: 10px auto;
      padding: 0 25px;
      border-bottom: 1px solid #000000;
      cursor: pointer;
  }
  
  .done {
    opacity: 0.5;
    text-decoration: line-through;
  }
<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>오늘 할 일</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="main">
    <h2 class="title">오늘 할 일</h2>
    <div class="add-container">
      <input class="add-input" type="text">
      <button class="add-btn">Add</button>
    </div>
    <ul class="list"></ul>
  </div>
  <script src="main.js"></script>
</body>
</html>

03. 셜록 훈즈

const quiz = ['YUMMY', 'COUNT', 'ABUSE', 'SOUND', 'SWING'];


const answer = quiz.map((value,i)=> {
  return value[i];
});


// 테스트 코드
console.log(answer);

04. 배열 메소드Ⅱ. filter와 find 

#filter

: 조건을 만족하는 모든 요소들을 배열로 리턴 

- 조건 만족하는 요소 없으면 [] 리턴

# find 

: 조건을 만족하는 최상위 요소 하나만 리턴 

- 조건 만족하는 요소 없으면 undefined 

const devices = [
  {name : 'GalaxyNote1', brand : 'Sansung'},
  {name : 'iPhone', brand : 'apple'},
  {name : 'SurfacePro', brand : 'MS'},
  {name : 'GalaxyWatch', brand : 'Sansung'},
  {name : 'iMac', brand : 'apple'},
  {name : 'Gram', brand : 'LG'},
  {name : 'GalaxyBuds', brand : 'Sansung'},
  {name : 'iPad', brand : 'apple'},
]

const apples = devices.filter((el)=> el.brand === 'apple');
console.log(apples); // (3) [{…}, {…}, {…}]

const apple = devices.find((el)=> el.brand === 'apple');
console.log(apple); //{name: 'iPhone', brand: 'apple'}

05. 서울 김서방 찾지 않기

const seoul = ['김영훈', '김윤수', '김동욱', '강대위', '김영준',
  '김규식', '김태호', '김효신', '손효준', '김현승', '김재하', '김유나',
  '김재훈', '김혜선', '김민환', '김규리', '김소원', '김우재', '최영준',
  '김태순', '김종훈', '김성환', '김승용', '김지혜', '이승욱', '김도현',
  '김승규', '윤하은', '김유진', '김정민', '김혜정', '김예진', '김여진',
  '김성희', '김혜수', '김인선', '김상필', '김혜진', '서상원', '김상혜',
  '김민기', '김그루', '김희지'];

const notKims = seoul.filter((value)=>value[0]!=='김')

console.log(notKims); //['강대위', '손효준', '최영준', '이승욱', '윤하은', '서상원']

06. 이메일 찾기 

const nameInput = document.querySelector('#user-name');
const phoneInput = document.querySelector('#phone-number');
const findBtn = document.querySelector('#find');

const data = [
  { userName: '막대기', phoneNumber: '01012341111', email: 'stick@go_do_it.kr' },
  { userName: 'young', phoneNumber: '01012342222', email: 'kang@go_do_it.kr' },
  { userName: '코린이', phoneNumber: '01012343333', email: 'corin2@go_do_it.kr' },
  { userName: 'captain', phoneNumber: '01012344444', email: 'crew@go_do_it.kr' },
  { userName: 'YH', phoneNumber: '01012345555', email: 'whyH@go_do_it.kr' },
  { userName: '망고쥬스', phoneNumber: '01012346666', email: 'drinkMango@go_do_it.kr' },
  { userName: 'nemoming', phoneNumber: '01012347777', email: 'ractAngle@go_do_it.kr' },
  { userName: '강그루', phoneNumber: '01012348888', email: 'riverTree@go_do_it.kr' },
  { userName: '개룩발룩', phoneNumber: '01012349999', email: 'checkShirts@go_do_it.kr' },
  { userName: '오렌지쥬스', phoneNumber: '01012341010', email: 'delmonte@go_do_it.kr' },
];

function findEmail() {
  const nameValue = nameInput.value;
  const phoneValue = phoneInput.value;

  // 여기에 코드를 작성해 주세요.
  const user = data.find((el)=> nameValue===el.userName && phoneValue===el.phoneNumber);

  const message = user
    ? `${user.userName}님의 이메일은 ${user.email} 입니다.`
    : '이메일을 찾을 수 없습니다. 입력 정보를 다시 확인해 주세요.';

  alert(message);
}

findBtn.addEventListener('click', findEmail);

- 일치하는 데이터가 없을 경우 undefined를 반환하므로 삼항연산자의 조건이 false가 됨 

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <title>이메일 찾기</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="main">
    <h2 class="title">이메일 찾기</h2>
    <input id="user-name" class="input" type="text" placeholder="User Name">
    <input id="phone-number" class="input" type="text" placeholder="Phone Number">
    <button id="find" class="btn">Find</button>
  </div>
  <script src="main.js"></script>
</body>
</html>
* {
    box-sizing: border-box;
  }
  
  body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      padding: 0;
    background-image: url('imgs/background.jpg');
    background-position: right;
      background-size: cover;
      background-repeat: no-repeat;
  }
  
  body::after {
      display: block;
      content: '';
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      background-color: #ababac;
      opacity: 0.3;
      z-index: -1;
  }
  
  .main {
      width: 360px;
      min-height: 350px;
      margin: 40px;
    padding: 20px 0;
    background-color: rgba(235, 236, 240, .95);
    box-shadow: 0px 0px 10px #BABECC;
    border-radius: 8px;
    text-align: center;
  }
  
  .title {
      margin: 20px auto 35px;
      font-size: 32px;
      font-weight: 900;
    color: #545454;
    text-shadow: 1px 1px 1px #FFFFFF;
  }
  
  .input {
    display: block;
    width: 80%;
    height: 50px;
    margin: 10px auto;
    padding: 10px 20px;
    font-size: 16px;
    text-shadow: 1px 1px 0 #ffffff;
    box-shadow: inset 2px 2px 5px #BABECC, inset -5px -5px 10px #FFFFFF;
    background-color: #EBECF0;
    border: none;
    border-radius: 320px;
    transition: all 0.2s ease-in-out;
    outline: none;
    appearance: none;
    -webkit-appearance: none;
  }
  
  .input:focus {
    box-shadow:  inset 1px 1px 2px #BABECC, inset -1px -1px 2px #FFFFFF;
  }
  
  .btn {
    width: 80%;
    height: 50px;
    margin-top: 20px;
    border: none;
    border-radius: 320px;
    font-size: 20px;
    font-weight: 600;
    color: #545454;
    text-shadow: 1px 1px 0 #ffffff;
    box-shadow: -5px -5px 20px #FFFFFF, 5px 5px 20px #BABECC;
    transition: all 0.2s ease-in-out;
    cursor: pointer;
    outline: none;
  }
  
  .btn:hover {
    box-shadow: -2px -2px 5px #FFFFFF, 2px 2px 5px #BABECC;
  }
  
  .btn:active {
    box-shadow: inset 1px 1px 2px #BABECC, inset -1px -1px 2px #FFFFFF;
  }

07. 배열 메소드Ⅲ. some과 every 

# some 

: 조건을 만족하는 요소가 1개 이상 있는지 검사 

- true / false 리턴

- 조건을 만족하는 요소 찾는 순간 true를 리턴하고 반복 종료

# every

: 모든 요소가 조건을 만족하는지 (조건을 만족하지 않는 요소가 1개라도 있는지) 검사 

- true / false 리턴

- 조건을 만족하지 않는 요소를 찾는 순간 false를 리턴하고 반복 종료 

const numbers = [1,3,5,7,9];

const someReturn = numbers.some((el)=> el>5);
const everyReturn = numbers.every((el)=> el>5);

console.log(someReturn); //true 
console.log(everyReturn); //false

08. 이 중 스파이가 있다 

const spait = [
  { codeName: 'ApplePie', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
  { codeName: 'BigBoss', members: ['스파이', '스파이', '스과이', '스파이', '스파이'] },
  { codeName: 'CEO', members: ['스파이', '스파이', '스파이', '습하이', '스파이'] },
  { codeName: 'DeathNote', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
  { codeName: 'EarlyBird', members: ['스파이', '스마이', '스파이', '스파이', '스파이'] },
  { codeName: 'Faker', members: ['스파이', '스파이', '스파이', '스파이', '스파이'] },
];

function checkSpy(team) {
  message = team.members.every((el)=>el === '스파이') 
  ? `팀 ${team.codeName} 에는 이중 스파이가 없습니다.`
  : `[주의!] 팀 ${team.codeName} 에 이중 스파이가 있습니다!`
	console.log(message);
}

// 테스트 코드
spait.forEach((team) => checkSpy(team));

09. 배열 메소드Ⅳ. reduce

# some 

:  배열의 각 요소에 대해 주어진 리듀서(reducer) 함수를 실행하고, 하나의 결과값을 반환

 

(method) Array<number>.reduce<any>(callbackfn: (previousValue: any, currentValue: number, currentIndex: number, array: number[]) => any, initialValue: any): any (+2 overloads)

 

numbers.reduce((acc,el,i,arr)=>{
  return nextAccValue;
}, initialAccValue);
 
const numbers = [1,2,3,4];

const sumAll = numbers.reduce((acc,el,i)=>{
  console.log(`${i}번 index의 요소로 콜백함수가 동작중`);
  console.log('acc : ',acc);
  console.log('el : ',el);
  console.log('==========');

  return acc + el;
},0);

console.log('sumAll : ',sumAll); //10

 


10. 세계적인 경력의 소유자 

const data = [ 
  { company: 'Naber', month: 3 },
	{ company: 'Amajohn', month: 12 },
	{ company: 'Coogle', month: 10 },
  { company: 'Ittel', month: 6 },
  { company: 'Sasung', month: 4 },
  { company: 'CaCao', month: 3 },
	{ company: 'Microhard', month: 17 },
];

const totalCareer = data.reduce((acc,el)=>{
  return acc+el.month
},0);

console.log(`상원이의 경력은 총 ${totalCareer}개월입니다.`);

11. sort, reverse 

# sort 메소드

: 배열을 정렬

- sort 메소드에 아무런 아규먼트도 전달하지 않을 때는 기본적으로  유니코드에 정의된 문자열 순서에 따라 정렬

- 메소드를 실행하는 원본 배열의 요소들을 정렬 

const letters = ['D', 'C', 'E', 'B', 'A'];
const numbers = [1, 10, 4, 21, 36000];

letters.sort();
numbers.sort();

console.log(letters); // (5) ["A", "B", "C", "D", "E"]
console.log(numbers); // (5) [1, 10, 21, 36000, 4]

- 오름차순 / 내림차순 정렬 방법 

const numbers = [1, 10, 4, 21, 36000];

// 오름차순 정렬
numbers.sort((a, b) => a - b);
console.log(numbers); // (5) [1, 4, 10, 21, 36000]

// 내림차순 정렬
numbers.sort((a, b) => b - a);
console.log(numbers); // (5) [36000, 21, 10, 4, 1]

 

# reverse 메소드

: 배열의 순서를 뒤집어 주는 메소드

- reverse 메소드는 별도의 파라미터가 존재x

- 단순히 메소드를 호출해주기만 하면 배열의 순서가 뒤집힘

- 원본 배열의 요소들을 뒤집힘

const letters = ['a', 'c', 'b'];
const numbers = [421, 721, 353];

letters.reverse();
numbers.reverse();

console.log(letters); // (3) ["b", "c", "a"]
console.log(numbers); // (3) [353, 721, 421]

12. Map, Set

# Map

- 이름이 있는 데이터를 저장한다는 점에서 객체와 비슷

-  Map은 메소드를 통해서 값을 추가하거나 접근할 수 있음 

- new 키워드를 통해서 Map을 생성

- 아래와 같은 메소드를 통해 Map 안의 여러 값들을 다룰 수 있음 

  • map.set(key, value): key를 이용해 value를 추가하는 메소드.
  • map.get(key): key에 해당하는 값을 얻는 메소드. key가 존재하지 않으면 undefined를 반환.
  • map.has(key): key가 존재하면 true, 존재하지 않으면 false를 반환하는 메소드.
  • map.delete(key): key에 해당하는 값을 삭제하는 메소드.
  • map.clear(): Map 안의 모든 요소를 제거하는 메소드.
  • map.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)
// Map 생성
const codeit = new Map();

// set 메소드
codeit.set('title', '문자열 key');
codeit.set(2017, '숫자형 key');
codeit.set(true, '불린형 key');

// get 메소드
console.log(codeit.get(2017)); // 숫자형 key
console.log(codeit.get(true)); // 불린형 key
console.log(codeit.get('title')); // 문자열 key

// has 메소드
console.log(codeit.has('title')); // true
console.log(codeit.has('name')); // false

// size 프로퍼티
console.log(codeit.size); // 3

// delete 메소드
codeit.delete(true);
console.log(codeit.get(true)); // undefined
console.log(codeit.size); // 2

// clear 메소드
codeit.clear();
console.log(codeit.get(2017)); // undefined
console.log(codeit.size); // 0

- Map 객체는 메소드를 통해 값을 다루기 때문에, 다양한 자료형을 key로 활용할 수 있음 

 

# Set

- 여러 개의 값을 순서대로 저장

- 배열의 메소드는 활용할 수 없고 Map과 비슷하게 Set만의 메소드를 통해서 값을 다룸

- Map과 마찬가지로 new 키워드로 Set을 생성

- 아래와 같은 메소드를 통해 Set 안의 여러 값들을 다룰 수 있음

  • set.add(value): 값을 추가하는 메소드. (메소드를 호출한 자리에는 추가된 값을 가진 Set 자신을 반환.)
  • set.has(value): Set 안에 값이 존재하면 true, 아니면 false를 반환하는 메소드.
  • set.delete(value): 값을 제거하는 메소드. (메소드를 호출한 자리에는 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환.)
  • set.clear(): Set 안의 모든 요소를 제거하는 메소드.
  • set.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)
// Set 생성
const members = new Set();

// add 메소드
members.add('영훈'); // Set(1) {"영훈"}
members.add('윤수'); // Set(2) {"영훈", "윤수"}
members.add('동욱'); // Set(3) {"영훈", "윤수", "동욱"}
members.add('태호'); // Set(4) {"영훈", "윤수", "동욱", "태호"}

// has 메소드
console.log(members.has('동욱')); // true
console.log(members.has('현승')); // false

// size 프로퍼티
console.log(members.size); // 4

// delete 메소드
members.delete('종훈'); // false
console.log(members.size); // 4
members.delete('태호'); // true
console.log(members.size); // 3

// clear 메소드
members.clear();
console.log(members.size); // 0

-  Set에는 개별 값에 바로 접근하는 방법이 없음

-  Set은 중복되는 값을 허용하지 않음

// Set 생성
const members = new Set();

// add 메소드
members.add('영훈'); // Set(1) {"영훈"}
members.add('윤수'); // Set(2) {"영훈", "윤수"}
members.add('영훈'); // Set(2) {"영훈", "윤수"}
members.add('영훈'); // Set(2) {"영훈", "윤수"}
members.add('동욱'); // Set(3) {"영훈", "윤수", "동욱"}
members.add('동욱'); // Set(3) {"영훈", "윤수", "동욱"}
members.add('동욱'); // Set(3) {"영훈", "윤수", "동욱"}
members.add('태호'); // Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('동욱'); // Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('태호'); // Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('태호'); // Set(4) {"영훈", "윤수", "동욱", "태호"}

- 최초에 추가된 순서를 유지하면서, 나중에 중복된 값을 추가하려고 하면 그 값은 무시

- 처음 Set을 생성할 때 아규먼트로 배열을 전달하는 특징을 활용해서 배열 내에서 중복을 제거한 값들의 묶음을 만들 때 Set을 활용

const numbers = [1, 3, 4, 3, 3, 3, 2, 1, 1, 1, 5, 5, 3, 2, 1, 4];
const uniqNumbers = new Set(numbers);

console.log(uniqNumbers); // Set(5) {1, 3, 4, 2, 5}
profile

DEVELOP

@JUNGY00N