Data Structures, Modern Operators and Strings

vancouver·2023년 6월 6일
0

javascript이해하기

목록 보기
14/22

배열 파괴

const restaurant = {
  name: "Classico Italiano",
  location: "Via Angelo Tavanti 23, Firenze, Italy",
  categories: ["Italian", "Pizzeria", "Vegetarian", "Organic"],
  starterMenu: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"],
  mainMenu: ["Pizza", "Pasta", "Risotto"],

  order: function (starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    sat: {
      open: 0, // Open 24 hours
      close: 24,
    },
  },
};

// Destructuring Arrays
const arr = [2, 3, 4];
const a = arr[0];
const b = arr[1];
const c = arr[2];

const [x, y, z] = arr;
console.log(x, y, z); // 2 3 4
console.log(arr); //[2, 3, 4]

let [main, , secondary] = restaurant.categories;
console.log(main, secondary); // Italian Vegetarian (let을 이용)

// switching variables
const temp = main;
main = secondary;
secondary = temp;
console.log(main, secondary); // Vegetarian Italian (순서를 바꿈)

[main, secondary] = [secondary, main];
console.log(main, secondary); // Italian Vegetarian (let보다 간편한 방법)

//Receive 2 return values from a function
const [starter, mainCourse] = restaurant.order(2, 0);
console.log(starter, mainCourse); // Garlic Bread Pizza

// Nested destructuring
const nested = [2, 4, [5, 6]];

const [i, , j] = nested;
 console.log(i, j); // 2 [5,6] 

const [i, , [j, k]] = nested;
 console.log(i, j, k); // 2 5 6 (배열안의 또다른 배열을 중복으로 파괴)

// default values
const [p, q, r] = [8, 9];
 console.log(p, q, r); // 8 9 undefined

const [p = 1, q = 1, r = 1] = [8, 9]; // = 1 을 넣으면 undefined에서 1로 바뀜
 console.log(p, q, r); // 8 9 1

객체 파괴

const restaurant = {
  name: "Classico Italiano",
  location: "Via Angelo Tavanti 23, Firenze, Italy",
  categories: ["Italian", "Pizzeria", "Vegetarian", "Organic"],
  starterMenu: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"],
  mainMenu: ["Pizza", "Pasta", "Risotto"],

  order: function (starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    sat: {
      open: 0, // Open 24 hours
      close: 24,
    },
  },

  orderDelivery: function ({ 
    starterIndex = 1,
    mainIndex = 0,
    time = `20:00`,
    address,
  }) {
    console.log(
      `Order received! ${this.starterMenu[starterIndex]} and ${this.mainMenu[mainIndex]} will be delivered to ${address} at ${time}`
    );
  },
};

restaurant.orderDelivery({ // 여기 안에 있는 변수들로 반영
  time: `22:30`,
  address: `Via del Sole, 21`,
  mainIndex: 2,
  starterIndex: 2,
});// Order received! Garlic Bread and Risotto will be delivered to Via del Sole, 21 at 22:30

restaurant.orderDelivery({// address, starterIndex 밖의 범위는 function 변수들로 반영
  address: `Via del Sole, 21`,
  starterIndex: 1,
}); // Order received! Bruschetta and Pizza will be delivered to Via del Sole, 21 at 20:00

const { name, openingHours, categories } = restaurant;
console.log(name, openingHours, categories);
//Classico Italiano {thu: {…}, fri: {…}, sat: {…}} (4) ['Italian', 'Pizzeria', 'Vegetarian', 'Organic']
const { // 변수들의 이름을 따로 정의가 가능
  name: restaurantName,
  openingHours: hours,
  categories: tags,
} = restaurant;

console.log(restaurantName, hours, tags);
//Classico Italiano {thu: {…}, fri: {…}, sat: {…}} (4) ['Italian', 'Pizzeria', 'Vegetarian', 'Organic']

// Default values (변수의 값을 바꿀수있음)
const { menu = [], starterMenu: starters = [] } = restaurant;
console.log(menu, starters);
// [] (4) ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad']

// Mutating variables
let a = 111;
let b = 999;
const obj = { a: 23, b: 7, c: 14 };
({ a, b } = obj);
console.log(a, b);
// 23 7

// Nested objects
const {
  fri: { open: o, close: c },
} = openingHours;
console.log(o, c);
// 11 23

스프레드 연산자

스프레드 연산자를 사용하면 쉼표로 값을 구분이 가능

const arr = [7, 8, 9];
const badNewArr = [1, 2, arr[0], arr[1], arr[2]];
console.log(badNewArr); // [1,2,7,8,9]

const newArr = [1, 2, ...arr]; // [1,2,7,8,9] (...으로 배열의 전체를 보여줌)
console.log(newArr);

console.log(...newArr); // 1 2 7 8 9
console.log(1, 2, 7, 8, 9); //1 2 7 8 9

const newMenu = [...restaurant.mainMenu, `Gnocci`];
console.log(newMenu);  //  ['Pizza', 'Pasta', 'Risotto', 'Gnocci'] // Gnocci를 추가

스프레드 연산자를 이용한 예제

const restaurant = {
  
 orderPasta: function (ing1, ing2, ing3) {
    console.log(
      `Here is your delicious pasta with ${ing1}, ${ing2} and ${ing3}`
    ); // Real-World example에 반영된 메뉴
 },
};
// Copy array
const mainMenu = [...restaurant.mainMenu];

// Join 2 Arrays
const menu = [...restaurant.starterMenu, ...restaurant.mainMenu];
console.log(menu); 
// ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad', 'Pizza', 'Pasta', 'Risotto'] (starterMenu,mainMenu의 배열을 다 불러옴)

// Iterables: arrays, strings, maps, sets, NOT objects
const str = `Jang`;
const letters = [...str, ` `, `S.`];
console.log(letters); //  ['J', 'a', 'n', 'g', ' ', 'S.'] 배열을 만듬
console.log(...str); // J a n g 나열함
console.log(`${...str} Hoon`); // Uncaught SyntaxError: Unexpected token '...' ($ 토큰에는 액세스가안됨)

// Real-world example 
const ingredients = [
   prompt("Let`s make Pasta! Ingredients 1?"), 
   prompt("Ingredients 2?"), 	 
   prompt("Ingredients 3?"), 	
];

console.log(ingredients);


restaurant.orderPasta(ingredients[0], ingredients[1], ingredients[2]); // 스프레드 연사자를 이용하지 않은 경우
restaurant.orderPasta(...ingredients);  // 스프레드 연산자를 이용한 경우


/* Objects */
const newRestaurant = { foundedIn: 1998, ...restaurant, founder: `Guiseppe` }; /* object를 추가 */

console.log(newRestaurant); // {foundedIn: 1998, name: 'Classico Italiano', location: 'Via Angelo Tavanti 23, Firenze, Italy', categories: Array(4), starterMenu: Array(4), …}

const resaturantCopy = { ...restaurant }; // 배열의 수정이 필요할때 
resaturantCopy.name = `Ristorant Roma`;
console.log(resaturantCopy.name); //Ristorant Roma
console.log(restaurant.name); //Classico Italiano

Rest Pattern

Rest 패턴을 사용하면 쉼표로 분리된 변수 이름을 쓸때 사용

 orderPizza: function (mainIngredient, ...otherIngredients) {
    console.log(mainIngredient); //mushrooms

    console.log(otherIngredients); //(3) ['onion', 'olives', 'spinach']
  },
};
// 1) Destructuring

// SPREAD, because on RIGHT side of =
const arr = [1, 2, ...[3, 4]];

// REST, because on LEFT side of =
const [a, b, ...others] = [1, 2, 3, 4, 5];
console.log(a, b, others); // 1 2 (3) [3, 4, 5]

const [pizza, , risotto, ...otherFood] = [
  ...restaurant.mainMenu,
  ...restaurant.starterMenu,
];
console.log(pizza, risotto, otherFood); // Pizza Risotto (4) ['Focaccia', 'Bruschetta', 'Garlic Bread', 'Caprese Salad']

// Objects
const { sat, ...weekdays } = restaurant.openingHours;
console.log(weekdays); // {thu: {…}, fri: {…}}

// 2) Functions
const add = function (...numbers) {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) sum += numbers[i];
  console.log(sum); // 5
  //25
  //17
  //35
};

add(2, 3);
add(5, 3, 7, 2);
add(8, 2, 5, 3, 2, 1, 4);

const x = [23, 5, 7];
add(...x);

restaurant.orderPizza(`mushrooms`, `onion`, `olives`, `spinach`); // orderPizza : function  (mushrooms 다음 단락에서 (3) ['onion', 'olives', 'spinach'])
restaurant.orderPizza(`mushrooms`); // mushrooms 다음 단락에서 []

&& , ||

|| 의 경우 둘 중 하나라도 참이면 뒤에 참이든 거짓이든 처음이 먼저 출력
&& 의 경우 우선순위로 출력

// Use Any data type, return ANY data type, short-circuiting
console.log(`------OR-------`);

console.log(3 || `Jang`); // 3
console.log(`` || `Jang`); // Jang
console.log(true || 0); // true
console.log(undefined || null); // null
console.log(undefined || 0 || `` || `Hello` || 23 || null); // Hello

restaurant.numGuests = 23;
const guest1 = restaurant.numGuests ? restaurant.numGuests : 10;
console.log(guest1); // 23

const guest2 = restaurant.numGuests || 10;
console.log(guest2); // 23

console.log(`------AND-------`);
console.log(0 && `Jang`); // 0
console.log(7 && `Jang`); // Jang

console.log(`Hello` && 23 && null && `Jang`); // null

// Practice Example
if (restaurant.orderPizza) {
  restaurant.orderPizza(`mushrooms`, `spinach`); // mushrooms ['spinach']
}

restaurant.orderPizza && restaurant.orderPizza(`mushrooms`, `spinach`); //// mushrooms ['spinach']

??

restaurant.numGuests = 0;
const guests = restaurant.numGuests || 10; // 10
console.log(guests);

// Nullish: null and undefined (NOT 0 or ``)
const guestCorrect = restaurant.numGuests ?? 10; // 0
console.log(guestCorrect);

Logical Assignment Operators

const rest1 = {
  name: `Carpi`,
  numGuests: 20,
  // numGuests: 0,
};

const rest2 = {
  name: `La Piazza`,
  owner: `Giovanni Rossi`,
};

// OR assignment operator
rest1.numGuests = rest1.numGuests || 10; // 20
rest2.numGuests = rest2.numGuests || 10; // 10

rest1.numGuests ||= 10; // 20
rest2.numGuests ||= 10; // 10

// nullish assignment operator (null or undefined)
rest1.numGuests ??= 10; // 0
rest2.numGuests ??= 10; // 10

// AND assignment operator
rest1.owner = rest1.owner && `<ANONYMOUS>`; //{name: 'Carpi', numGuests: 0, owner: undefined}
rest2.owner = rest2.owner && `<ANONYMOUS>`; //{name: 'La Piazza', owner: '<ANONYMOUS>', numGuests: 10}

rest1.owner &&= `<ANONYMOUS>`; // {name: 'Carpi', numGuests: 0}
rest2.owner &&= `<ANONYMOUS>`; // {name: 'La Piazza', owner: '<ANONYMOUS>', numGuests: 10}

console.log(rest1);
console.log(rest2);

Looping Arrays : for-of loop

// for of loop
const menu = [...restaurant.starterMenu, ...restaurant.mainMenu];
for (const item of menu) console.log(item);
/*
Focaccia
Bruschetta
Garlic Bread
Caprese Salad
Pizza
Pasta
Risotto */

// 구시대적 (아래식과 같다)
for (const item of menu.entries()) {
  console.log(`${item[0] + 1}: ${item[1]}`);
}
/*
1: Focaccia
2: Bruschetta
3: Garlic Bread
4: Caprese Salad
5: Pizza
6: Pasta
7: Risotto */

// 현대적 (위에 식과 같다)
for (const [i, el] of menu.entries()) {
  console.log(`${i + 1}: ${el}`);
}
/*
1: Focaccia
2: Bruschetta
3: Garlic Bread
4: Caprese Salad
5: Pizza
6: Pasta
7: Risotto */

console.log([...menu.entries()]);
// (7) [Array(2), Array(2), Array(2), Array(2), Array(2), Array(2), Array(2)]

Enhanced Object Literals

변경 전


const restaurant = {
  name: "Classico Italiano",
  location: "Via Angelo Tavanti 23, Firenze, Italy",
  categories: ["Italian", "Pizzeria", "Vegetarian", "Organic"],
  starterMenu: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"],
  mainMenu: ["Pizza", "Pasta", "Risotto"],

  order : function(starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

openingHours : {
  thu: {
    open: 12,
    close: 22,
  },
  fri: {
    open: 11,
    close: 23,
  },
  sat: {
    open: 0, // Open 24 hours
    close: 24,
  },
},


  orderDelivery: function({ starterIndex = 1, mainIndex = 0, time = `20:00`, address }) {
    console.log(
      `Order received! ${this.starterMenu[starterIndex]} and ${this.mainMenu[mainIndex]} will be delivered to ${address} at ${time}`
    );
  },

  orderPasta: function(ing1, ing2, ing3) {
    console.log(
      `Here is your delicious pasta with ${ing1}, ${ing2} and ${ing3}`
    );
  },

  orderPizza: function(mainIngredient, ...otherIngredients) {
    console.log(mainIngredient); //mushrooms

    console.log(otherIngredients); //(3) ['onion', 'olives', 'spinach']
  },
};

function 과 객체를 좀 더 간편화

const weekdays = [`mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`];

const openingHours = {
  [weekdays[3]]: {
    open: 12,
    close: 22,
  },
  [weekdays[4]]: {
    open: 11,
    close: 23,
  },
  [weekdays[5]]: {
    open: 0, // Open 24 hours
    close: 24,
  },
};

const restaurant = {
  name: "Classico Italiano",
  location: "Via Angelo Tavanti 23, Firenze, Italy",
  categories: ["Italian", "Pizzeria", "Vegetarian", "Organic"],
  starterMenu: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"],
  mainMenu: ["Pizza", "Pasta", "Risotto"],

  order(starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

  // ES6 enhanced object literals
  openingHours,

  orderDelivery({ starterIndex = 1, mainIndex = 0, time = `20:00`, address }) {
    console.log(
      `Order received! ${this.starterMenu[starterIndex]} and ${this.mainMenu[mainIndex]} will be delivered to ${address} at ${time}`
    );
  },

  orderPasta(ing1, ing2, ing3) {
    console.log(
      `Here is your delicious pasta with ${ing1}, ${ing2} and ${ing3}`
    );
  },

  orderPizza(mainIngredient, ...otherIngredients) {
    console.log(mainIngredient); //mushrooms

    console.log(otherIngredients); //(3) ['onion', 'olives', 'spinach']
  },
};

Optional Chaining

const openingHours = {
  [weekdays[3]]: {
    open: 12,
    close: 22,
  },
  [weekdays[4]]: {
    open: 11,
    close: 23,
  },
  [weekdays[5]]: {
    open: 0, // Open 24 hours
    close: 24,
  },
};
starterMenu: ["Focaccia", "Bruschetta", "Garlic Bread", "Caprese Salad"],
  mainMenu: ["Pizza", "Pasta", "Risotto"],
    
order(starterIndex, mainIndex) {
    return [this.starterMenu[starterIndex], this.mainMenu[mainIndex]];
  },

// WITH optional chaining
console.log(restaurant.openingHours.mon?.open); // undefined
console.log(restaurant.openingHours?.mon?.open); // undefined

// Example
const days = [`mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`];
for (const day of days) {
  const open = restaurant.openingHours[day]?.open ?? `closed`;
  console.log(`On ${day}, we open at ${open}`);
  /*On mon, we open at closed
    On tue, we open at closed
    On wed, we open at closed
    On thu, we open at 12
    On fri, we open at 11
    On sat, we open at 0
    On sun, we open at closed */
}

// Methods
console.log(restaurant.order?.(0, 1) ?? `Method does not exist`); // ['Focaccia', 'Pasta']
console.log(restaurant.orderRissoto?.(0, 1) ?? `Method does not exist`); // Method does not exist

// Arrays
const users = [{ name: `Jang`, email: `hello@vancouver.io` }];
// const users = [];


// 아래와 같음
console.log(users[0]?.name ?? `Users array empty`); // Jang

// 위와 같음
if (users.length > 0) console.log(users[0].name);
else console.log(`Users array empty`); // Jang

Looping Objects: Object Keys, Values, and Entries

// Property NAMES
const properties = Object.keys(openingHours);
console.log(properties); // (3) ['thu', 'fri', 'sat']

let openStr = `We are open on ${properties.length} days: `;
for (const day of properties) {
  openStr += `${day}, `;
}
console.log(openStr); // We are open on 3 days: thu, fri, sat,

// Property VALUES
const values = Object.values(openingHours);
console.log(values);
/* (3) [{…}, {…}, {…}]
0: {open: 12, close: 22}
1: {open: 11, close: 23}
2: {open: 0, close: 24}
length: 3
[[Prototype]]: Array(0) */

// Entire object
const entries = Object.entries(openingHours);
console.log(entries);
/* (3) [Array(2), Array(2), Array(2)]
0: Array(2)
  0: "thu"
  1: {open: 12, close: 22}
  length: 2
  [[Prototype]]: Array(0)

1: (2) ['fri', {…}]

2: (2) ['sat', {…}]
length: 3
[[Prototype]]: Array(0) */

// [key, value]
for (const [key, { open, close }] of entries) {
  console.log(`On ${key} we open at ${open} and close at ${close}`);
}
/* On thu we open at 12 and close at 22
On fri we open at 11 and close at 23
On sat we open at 0 and close at 24 */

Coding Challenge #1 : Operator

  1. Create one player array for each team (variables 'players1' and 'players2')

    각 팀에 대해 하나의 플레이어 배열을 만듭니다(변수 'players1' 및 'players2').

  2. The first player in any player array is the goalkeeper and the others are field
    players. For Bayern Munich (team 1) create one variable ('gk') with the
    goalkeeper's name, and one array ('fieldPlayers') with all the remaining 10
    field players

    모든 선수 배열의 첫 번째 선수는 골키퍼이고 나머지는 필드 선수입니다. 바이에른 뮌헨(팀 1)의 경우
    골키퍼 이름, 나머지 10개 모두 포함된 하나의 배열('fieldPlayers') 필드 플레이어

  3. Create an array 'allPlayers' containing all players of both teams (22
    players

    양 팀의 모든 선수를 포함하는 'allPlayers' 배열을 생성합니다(22명의 선수)

  4. During the game, Bayern Munich (team 1) used 3 substitute players. So create a
    new array ('players1Final') containing all the original team1 players plus
    'Thiago', 'Coutinho' and 'Perisic'

  1. 경기 중 바이에른 뮌헨(1팀)은 교체 선수 3명을 투입했다. 따라서 모든 원래 팀 1 플레이어와 '티아고', '쿠티뉴' 그리고 '페리시치'
  1. Based on the game.odds object, create one variable for each odd (called
    'team1', 'draw' and 'team2')
  1. game.odds 개체를 기반으로 각 홀수에 대해 하나의 변수를 생성합니다('team1', '무승부' 및 'team2')
  1. Write a function ('printGoals') that receives an arbitrary number of player
    names (not an array) and prints each of them to the console, along with the
    number of goals that were scored in total (number of player names passed in)
  1. 임의의 수의 플레이어를 받는 함수('printGoals')를 작성합니다.
    이름(배열이 아님)을 지정하고 각각을 콘솔에 출력합니다.
    총 득점한 골 수(전달된 선수 이름 수)
  1. The team with the lower odd is more likely to win. Print to the console which team is more likely to win, without using an if/else statement or the ternary operator.
  1. 배당률이 낮은 팀이 이길 확률이 높습니다. if/else 문이나 삼항 연산자를 사용하지 않고 어떤 팀이 이길 가능성이 더 높은지 콘솔에 출력합니다.

Test data for 6.: First, use players 'Davies', 'Muller', 'Lewandowski' and 'Kimmich'.
Then, call the function again with players from game.scored

6에 대한 테스트 데이터: 먼저 'Davies', 'Muller', 'Lewandowski' 및 'Kimmich' 선수를 사용합니다. 그런 다음 game.scored의 플레이어와 함께 함수를 다시 호출합니다.

// 1. 배열 파괴 player1, player2로 나뉘는 과정
const [players1, players2] = game.players;
console.log(players1, players2);
// (11) ['Neuer', 'Pavard', 'Martinez', 'Alaba', 'Davies', 'Kimmich', 'Goretzka', 'Coman', 'Muller', 'Gnarby', 'Lewandowski'] 
// (11) ['Burki', 'Schulz', 'Hummels', 'Akanji', 'Hakimi', 'Weigl', 'Witsel', 'Hazard', 'Brandt', 'Sancho', 'Gotze']

// 2. 골키퍼와 fieldPlayers로 구분하는 과정
const [gk, ...fieldPlayers] = players1;
console.log(gk, fieldPlayers);
// Neuer 
// (10) ['Pavard', 'Martinez', 'Alaba', 'Davies', 'Kimmich', 'Goretzka', 'Coman', 'Muller', 'Gnarby', 'Lewandowski']

// 3. 모든 플레이어를 배열 파괴하여 모아놓는 과정
const allplayers = [...players1, ...players2];
console.log(allplayers);
// (22) ['Neuer', 'Pavard', 'Martinez', 'Alaba', 'Davies', 'Kimmich', 'Goretzka', 'Coman', 'Muller', 'Gnarby', 'Lewandowski', 'Burki', 'Schulz', 
//  'Hummels', 'Akanji', 'Hakimi', 'Weigl', 'Witsel', 'Hazard', 'Brandt', 'Sancho', 'Gotze']

// 4. 선수들을 추가하는 과정
const player1Final = [...players1, "Thiago", "Coutinho", `Perisic`];
console.log(player1Final);
// (14) ['Neuer', 'Pavard', 'Martinez', 'Alaba', 'Davies', 'Kimmich',
//'Goretzka', 'Coman', 'Muller', 'Gnarby', 'Lewandowski', 'Thiago', 'Coutinho', 'Perisic']

// 5. odds배열을 파괴
const {
  odds: { team1, x: draw, team2 },
} = game;

console.log(team1, draw, team2);
// 1.33 3.25 6.5

// 6. 선수들의 숫자만큼 점수를 내는 과정
const printGoals = function (...players) {
  console.log(players);
  console.log(`${players.length} goals were scored`);
};

printGoals("Davies", "Muller", "Lewandowski", "Kimmich");
printGoals("Davies", "Muller");

printGoals(...game.scored);

// 4) ['Davies', 'Muller', 'Lewandowski', 'Kimmich']0: "Davies"1: "Muller"2: "Lewandowski"3: "Kimmich"length: 4[[Prototype]]: Array(0)
// 4 goals were scored
// (2) ['Davies', 'Muller']
// 2 goals were scored
// (4) ['Lewandowski', 'Gnarby', 'Lewandowski', 'Hummels']
// 4 goals were scored


// 7. 각 팀의 승률을 판단
team1 < team2 && console.log(`Team 1 is more likely to win`); //Team 1 is more likely to win
team1 > team2 && console.log(`Team 2 is more likely to win`); //Team 2 is more likely to win

Coding Challenge #2

// 1. game.scored 배열을 순환하고 각 플레이어 이름과 골 번호를 콘솔에 출력합니다. (예: "Goal 1: Lewandowski")

for (const [i, player] of game.scored.entries()) {
  console.log(`Goal ${i + 1}: ${player}`);
}/* Goal 1: Lewandowski
	Goal 2: Gnarby
	Goal 3: Lewandowski
	Goal 4: Hummels */

// 2. 루프를 사용하여 평균 배당률을 계산하고 콘솔에 로그로 출력합니다. (평균을 계산하는 방법을 이미 배웠으므로, 기억이 나지 않는 경우 확인해볼 수 있습니다.)
const batting = Object.values(game.odds);

let average = 0;

for (const odd of batting) average += odd;
average /= batting.length;
console.log(`${average}`); // 3.6933333333333334

// 3. 3개의 배당률을 예쁘게 포맷팅하여 콘솔에 출력합니다. 다음과 같이 정확히 출력되어야 합니다:
// - Bayern Munich의 승리 배당률: 1.33
// - 무승부 배당률: 3.25
// - Borrussia Dortmund의 승리 배당률: 6.5
//    팀 이름은 game 객체에서 직접 가져와야 합니다. 하드코딩하지 마세요. ("draw"를 제외한 나머지 팀 이름)
//    힌트: 배당률과 game 객체가 동일한 속성 이름을 가지고 있는지 확인하세요.

for (const [team, odd] of Object.entries(game.odds)) {
  const teamStr = team === `x` ? `draw` : `victory ${game[team]}`;
  console.log(`Odd of ${teamStr} ${odd}`);
}/* 
Odd of victory Bayern Munich 1.33
Odd of draw 3.25
Odd of victory Borrussia Dortmund 6.5 */


// 4. 보너스: 'scorers'라는 객체를 생성하고, 득점한 선수 이름을 속성으로, 골 수를 값으로 가지도록 합니다. 이 게임에서는 다음과 같이 나타납니다:
// {
// Gnarby: 1,
// Hummels: 1,
// Lewandowski: 2
// }

Sets

배열안의 중복된 객체는 하나로만 정의

const ordersSet = new Set([
  `Pasta`,
  `Pizza`,
  `Pizza`,
  `Rissoto`,
  `Pasta`,
  `Pizza`,
]);

console.log(ordersSet); //Set(3) {'Pasta', 'Pizza', 'Rissoto'}

console.log(new Set(`Jang`)); //Set(4) {'J', 'a', 'n', 'g'}

console.log(ordersSet.size); // 3
console.log(ordersSet.has(`Pizza`)); // true (배열안의 유무를 확인)
console.log(ordersSet.has(`Bread`)); // false
ordersSet.add(`Garlic Bread`);
ordersSet.add(`Garlic Bread`); // Garlic Bread를 추가 (중복일 경우 하나만)
// ordersSet.clear();
console.log(ordersSet); // Set(4) {'Pasta', 'Pizza', 'Rissoto', 'Garlic Bread'}

for (const order of ordersSet) console.log(order);
/*Pasta
  Pizza
  Rissoto
  Garlic Bread*/

//Example
const staff = [`Waiter`, `Chef`, `Waiter`, `Manager`, `Chef`, `Waiter`];
const staffUnique = [...new Set(staff)];
console.log(staffUnique); //(3) ['Waiter', 'Chef', 'Manager']
console.log(
  new Set([`Waiter`, `Chef`, `Waiter`, `Manager`, `Chef`, `Waiter`]).size 
); // 3

Map

const rest = new Map();
rest.set(`name`, `Classico Italiano`);
rest.set(1, `Firenze, Italy`);
console.log(rest.set(2, `Lisbon, Portugal`));
/* Map(3) {'name' => 'Classico Italiano', 1 => 'Firenze, Italy', 2 => 'Lisbon, Portugal'}
[[Entries]]
0: {"name" => "Classico Italiano"}
1: {1 => "Firenze, Italy"}
2: {2 => "Lisbon, Portugal"}
3: {"categories" => Array(4)}
4: {"open" => 11}
5: {"close" => 23}
6: {true => "We are open :D"}
7: {false => "we are closed :("}
size: 8
[[Prototype]]: Map */

rest
  .set(`categories`, [`Italian`, `Pizzaria`, `Vegetarian`, `Organic`])
  .set(`open`, 11)
  .set(`close`, 23)
  .set(true, `We are open :D`)
  .set(false, `we are closed :(`);

console.log(rest.get(`name`)); // get(찾으려는 목표)
console.log(rest.get(true)); // true 나 false로도 가능
console.log(rest.get(1)); // Firenze, Italy

const time = 21; // time의 값을 11시부터 < x < 23시까지 운영한다.
console.log(rest.get(time > rest.get(`open`) && time < rest.get(`close`))); //  We are open :D

console.log(rest.has(`categories`));
rest.delete(2); // map 안의 객체를 삭제 하는 기능
//rest.clear(); // 초기화

const arr = [1, 2];
rest.set(arr, `Test`); // 배열을 추가하려면 변수를 통해서 추가해야함
rest.set(document.querySelector(`h1`), `Heading`); // map의 추가
/*8: {h1 => "Heading"}
  key: h1
  value: "Heading" */
console.log(rest);
/*Map(9) {'name' => 'Classico Italiano', 1 => 'Firenze, Italy', 'categories' => Array(4), 'open' => 11, 'close' => 23, …}
[[Entries]]0: {"name" => "Classico Italiano"}
1: {1 => "Firenze, Italy"}
2: {"categories" => Array(4)}
3: {"open" => 11}
4: {"close" => 23}
5: {true => "We are open :D"}
6: {false => "we are closed :("}
7: {Array(2) => "Test"}
8: {h1 => "Heading"}
size: 9
[[Prototype]]: Map
*/

console.log(rest.size); // 9

console.log(rest.get(arr)); // Test

Maps: Iteration

const question = new Map([
  [`question`, `What is the best programming language in the world?`],
  [1, `C`],
  [2, `Java`],
  [3, `JavaScript`],
  [`correct`, 3],
  [true, `Correct!`],
  [false, `Try again!`],
]);
console.log(
  question
); /*Map(7) {'question' => 'What is the best programming language in the world?', 1 => 'C', 2 => 'Java', 3 => 'JavaScript', 'correct' => 3, …}
[[Entries]]
0: {"question" => "What is the best programming language in the world?"}
1: {1 => "C"}
2: {2 => "Java"}
3: {3 => "JavaScript"}
4: {"correct" => 3}
5: {true => "Correct!"}
6: {false => "Try again!"}
size: 7
[[Prototype]]: Map
*/

// Convert object to map
console.log(Object.entries(openingHours));
/*
(3) [Array(2), Array(2), Array(2)]
0: (2) ['thu', {…}]
1: (2) ['fri', {…}]
2: (2) ['sat', {…}]
length: 3
[[Prototype]]: Array(0) */
const hoursMap = new Map(Object.entries(openingHours));
console.log(hoursMap);
/*
Map(3) {'thu' => {…}, 'fri' => {…}, 'sat' => {…}}
[[Entries]]
0: {"thu" => Object}
1: {"fri" => Object}
2: {"sat" => Object}
size: 3
[[Prototype]]: Map
*/

// Quiz app
console.log(question.get(`question`));
// What is the best programming language in the world?
for (const [key, value] of question) {
  if (typeof key === `number`) console.log(`Answer ${key}: ${value}`);
  /* Answer 1: C
     Answer 2: Java
     Answer 3: JavaScript */
}
// const answer = Number(prompt(`Your answer`));
const answer = 3;
console.log(answer);
// 3

console.log(question.get(question.get(`correct`) === answer));
// Correct!

// Convert map of array
console.log([...question]);
/* (7) [Array(2), Array(2), Array(2), Array(2), Array(2), Array(2), Array(2)]
  0: (2) ['question', 'What is the best programming language in the world?']
  1: (2) [1, 'C']
  2: (2) [2, 'Java']
  3: (2) [3, 'JavaScript']
  4: (2) ['correct', 3]
  5: (2) [true, 'Correct!']
  6: (2) [false, 'Try again!']
  length: 7
  [[Prototype]]: Array(0)
*/
// console.log(question.entries());
console.log([...question.values()]);
//(7) ['What is the best programming language in the world?', 'C', 'Java', 'JavaScript', 3, 'Correct!', 'Try again!']
console.log([...question.keys()]);
//(7) ['question', 1, 2, 3, 'correct', true, false]

요약: 어떤 데이터구조를 사용해야 할까?

1. 프로그램 내부에서: 소스 코드에 직접 작성된 데이터 (예: 상태 메시지)

2. UI에서: 사용자로부터 입력받은 데이터 또는 DOM에 작성된 데이터 (예: 할 일 앱의 작업)

3. 외부 소스에서: 웹 API에서 가져온 데이터 (예: 레시피 객체)

OHER BUILT-IN

  • WeakMap
  • WeakSet

NON BUILT-IN:

  • Stacks
  • Queues
  • Linked lists
  • Trees
  • Hash tables

Arrays vs. SETS

Arrays

tasks = [`Code`, `Eat`, `Code`]
// ["Code", "Eat", "Code"]
  1. 정렬된 값 목록(중복 가능)이 필요할 때 WeakMap을 사용하세요.

  2. 데이터를 조작해야 할 때 WeakMap을 사용하세요.

SETS

tasks = new Set([`Code`, `Eat`, `Code`])
// ["Code", "Eat"]
  1. 유일한 값과 작업해야 할 때 WeakMap을 사용하세요. WeakMap은 오직 객체만을 키로 사용하므로, 유일한 값을 유지하고 싶을 때 유용합니다.

  2. 성능이 매우 중요한 경우에 WeakMap을 사용하세요. WeakMap은 객체에 대한 약한 참조를 유지하므로, 메모리 관리 측면에서 효율적이고 빠른 성능을 제공할 수 있습니다.

  3. 배열에서 중복을 제거해야 할 때 WeakMap을 사용할 수 있습니다. WeakMap을 활용하여 중복되는 값을 효과적으로 제거할 수 있습니다. 예를 들어, 배열의 각 요소를 WeakMap의 키로 사용하고, 값은 true로 설정하여 중복을 제거할 수 있습니다.

Objects vs. Maps

Objects

task = {
  task: `Code`,
  date: `today`,
  repeat: true
};
  1. "전통적인" 키/값 저장소("오용된" 객체)를 더 많이 사용할 때 WeakMap을 사용합니다. WeakMap은 객체를 키로 사용하여 값을 저장하는 기능을 제공합니다. 이를 통해 객체를 키/값 저장소로 활용할 수 있습니다.

  2. "."과 "[]"를 사용하여 값을 쉽게 작성하고 액세스할 수 있습니다. WeakMap은 객체를 키로 사용하므로, "." 또는 "[]" 문법을 통해 값을 작성하고 액세스할 수 있습니다. 이를 통해 간편한 데이터 작성과 액세스가 가능합니다.

  3. 함수(메소드)를 포함해야 할 때 WeakMap을 사용하세요. WeakMap은 객체를 키로 사용하므로, 객체에 함수를 연결하여 함수를 포함한 데이터 구조를 만들 수 있습니다. 이를 통해 객체 내부에 함수를 캡슐화하고 적용할 수 있습니다.

  4. JSON과 함께 작업할 때 WeakMap을 사용할 수 있습니다. WeakMap은 객체를 키로 사용하므로, JSON 데이터를 객체로 변환한 후 WeakMap에 저장하고 관리할 수 있습니다. 이를 통해 JSON 데이터를 보다 편리하게 다룰 수 있습니다

Maps

task = new Map({
  [`task`, `Code`],
  [`date`, `today`],
  [false, `Start Coding`]
});
  1. 더 나은 성능: Map은 내부 구현에서 효율적인 데이터 액세스를 지원하여 더 빠른 성능을 제공할 수 있습니다. 특히 많은 양의 데이터를 다루거나 빈번한 조회 및 갱신 작업이 필요한 경우에 유리합니다.

  2. 키는 어떤 데이터 유형이든 가능: Map은 키로 어떤 데이터 유형이든 사용할 수 있습니다. 문자열뿐만 아니라 객체, 숫자, 불리언 등 다양한 유형의 키를 사용할 수 있습니다.

  3. 쉬운 반복(iteration): Map은 반복 가능한(iterable) 컬렉션이므로 for...of 루프 또는 Map의 내장 메서드를 사용하여 쉽게 반복(iteration)할 수 있습니다.

  4. 크기 계산이 용이: Map은 size 속성을 통해 저장된 항목의 개수를 쉽게 확인할 수 있습니다. 따라서 컬렉션의 크기를 계산하는 데 유용합니다.

  5. 키를 값에 매핑하는 단순한 매핑이 필요한 경우 사용하세요.
    Map은 각 키와 값을 매핑시키는 기능을 제공하므로, 키를 값에 연결하는 간단한 매핑 작업에 유용합니다.

  6. 문자열이 아닌 키가 필요한 경우 사용하세요.
    Map은 문자열이 아닌 키를 사용할 수 있는 유용한 데이터 구조입니다. 객체나 기타 데이터 유형을 키로 사용하여 더 다양한 키-값 쌍을 저장하고 조회할 수 있습니다.

Coding Challenge #3

// Coding Challenge #3

const gameEvents = new Map([
  [17, "⚽ GOAL"],
  [36, "🔁 Substitution"],
  [47, "⚽ GOAL"],
  [61, "🔁 Substitution"],
  [64, "🟨 Yellow card"],
  [69, "🟥 Red card"],
  [70, "🔁 Substitution"],
  [72, "🔁 Substitution"],
  [76, "⚽ GOAL"],
  [80, "⚽ GOAL"],
  [92, "🟨 Yellow card"],
]);

/* 
Let's continue with our football betting app! This time, we have a map called 
'gameEvents' (see below) with a log of the events that happened during the 
game. The values are the events themselves, and the keys are the minutes in which 
each event happened (a football game has 90 minutes plus some extra time).

함께 축구 베팅 앱을 계속 진행해봅시다! 이번에는 'gameEvents'라는 맵이 있습니다(아래 참조). 이 맵은 경기 동안 발생한 이벤트 기록을 담고 있습니다. 
값은 이벤트 자체이며, 키는 각 이벤트가 발생한 분(축구 경기는 90분과 추가 시간을 가집니다)입니다.

Your tasks:
/* 1. Create an array 'events' of the different game events that happened (no duplicates)

1.다른 게임 이벤트가 발생한 'events' 배열을 생성합니다. 중복된 이벤트는 포함되지 않아야 합니다. */
const events = new Set([...gameEvents.values()]);
console.log(events);
// Set(4) {'⚽ GOAL', '🔁 Substitution', '🟨 Yellow card', '🟥 Red card'}


// solution
const solution = [...new Set(gameEvents.values())];
console.log(solution);
// (4) ['⚽ GOAL', '🔁 Substitution', '🟨 Yellow card', '🟥 Red card']

/* 2. After the game has finished, is was found that the yellow card from minute 64 was unfair. So remove this event from the game events log.

2. 경기가 종료된 후, 64분에 발생한 옐로 카드가 부당하다는 것이 밝혀졌습니다. 따라서 이 이벤트를 게임 이벤트 로그에서 제거합니다.*/

console.log(gameEvents.delete(64));
// true

/* 3. Compute and log the following string to the console: "An event happened, on average, every 9 minutes" (keep in mind that a game has 90 minutes)

3. 다음 문자열을 계산하여 콘솔에 로그로 출력합니다: "평균적으로 9분마다 이벤트가 발생했습니다." (경기 시간은 90분임에 유의하세요)*/

const averageEventInterval = 90 / gameEvents.size;
console.log(
  `An event happened, on average, every ${averageEventInterval} minutes`
);
// An event happened, on average, every 9 minutes

// solution
console.log(
  `An event happened, on average, every ${90 / gameEvents.size} minutes`
);
// An event happened, on average, every 9 minutes

// Bonus
const time = [...gameEvents.keys()].pop();
console.log(time);
// 92
console.log(
  `An event happened, on average, every ${time / gameEvents.size} minutes`
);
// An event happened, on average, every 9.2 minutes


/* 4. Loop over 'gameEvents' and log each element to the console, marking whether it's in the first half or second half (after 45 min) of the game, 
like this: [FIRST HALF] 17: ⚽ GOAL

4. 'gameEvents'를 순환하며 각 요소를 콘솔에 로그로 출력하고, 경기의 전반인지 후반인지(45분 이후)를 표시합니다.   
다음과 같은 형식으로 출력합니다: [전반] 17분: ⚽ 골 */

for (const [minute, value] of gameEvents.entries()) {
  const half = minute <= 45 ? `First` : `Second`;

  console.log(`[${half} HALF] ${minute}: ${value}`);
}
/* [First HALF] 17: ⚽ GOAL
   [First HALF] 36: 🔁 Substitution
   [Second HALF] 47: ⚽ GOAL
   [Second HALF] 61: 🔁 Substitution
   [Second HALF] 69: 🟥 Red card
   [Second HALF] 70: 🔁 Substitution
   [Second HALF] 72: 🔁 Substitution
   [Second HALF] 76: ⚽ GOAL
   [Second HALF] 80: ⚽ GOAL
   [Second HALF] 92: 🟨 Yellow card */
//solution
for (const [min, event] of gameEvents) {
  const half = min <= 45 ? `FIRST` : `SECOND`;
  console.log(`[${half} HALF] ${min}: ${event}`);
}
/* [First HALF] 17: ⚽ GOAL
   [First HALF] 36: 🔁 Substitution
   [Second HALF] 47: ⚽ GOAL
   [Second HALF] 61: 🔁 Substitution
   [Second HALF] 69: 🟥 Red card
   [Second HALF] 70: 🔁 Substitution
   [Second HALF] 72: 🔁 Substitution
   [Second HALF] 76: ⚽ GOAL
   [Second HALF] 80: ⚽ GOAL
   [Second HALF] 92: 🟨 Yellow card */

0개의 댓글