프론트엔드/Javascript 연습과제 해답

자바스크립트 문법 13 - 함수(function)의 활용 해답

syleemomo 2022. 1. 26. 17:04
728x90

 

* 연습과제 1

해답 1

const fruit = 'apple'
let printB = null

function printA(){
    const fruit = 'banana'
    printB = function(){
        console.log(fruit) 
    }
    printB()
}



printA() // banana
printB() // banana

해답 2

const fruit = 'apple'
let printB = null

function printA() {
    const fruit = 'banana'
    function printB() {
        console.log(fruit)
    }
    printB()
    return printB
}



printB = printA() // banana
printB() // banana

 

* 연습과제 2

function filter(f, arr){
    const newArr = []
    let index = 0

    for(let i in arr){
        if(f(arr[i])){
            newArr[index] = arr[i]
            index++
        }
    }
    return newArr
}

function filterSeoul(friend){
    return friend.city === 'seoul'
}

const friends = [
    {name: 'victoria', age: 13, city: 'seoul'},
    {name: 'sun', age: 34, city: 'busan'},
    {name: 'johseb', age: 25, city: 'busan'},
    {name: 'syleemomo', age: 9, city: 'seoul'},
    {name: 'hannah', age: 41, city: 'daegu'},
    {name: 'shara', age: 37, city: 'seoul'},
    {name: 'martin', age: 28, city: 'daegu'},
    {name: 'gorgia', age: 39, city: 'seoul'},
    {name: 'nana', age: 24, city: 'busan'},
    {name: 'dannel', age: 19, city: 'seoul'},
]

const seoulFriends = filter(filterSeoul, friends)
console.log(seoulFriends)

 

* 연습과제 3

function add(a, b){
    return a + b
}
function subtract(a, b){
    return a - b
}
function multiply(a, b){
    return a * b
}
function divider(a, b){
    return a / b
}
function pow(a, b){
    let ret = 1
    for(let i=0 ; i<b; i++){
        ret *= a
    }
    return ret
}

function calculator(mode, a, b, ...funcs){
    let ret = null
    switch(mode){
        case '+':
            ret = funcs[0](a, b)
            break
        case '-':
            ret = funcs[1](a, b)
            break
        case '*':
            ret = funcs[2](a, b)
            break
        case '/':
            ret= funcs[3](a, b)
            break
        case '^':
            ret = funcs[4](a, b)
            break
    }
    return ret
}

// 테스트 케이스
const ret1 = calculator('+', 3, 4, add, subtract, multiply, divider, pow)
const ret2 = calculator('-', 3, 4, add, subtract, multiply, divider, pow)
const ret3 = calculator('*', 3, 4, add, subtract, multiply, divider, pow)
const ret4 = calculator('/', 3, 4, add, subtract, multiply, divider, pow)
const ret5 = calculator('^', 3, 4, add, subtract, multiply, divider, pow)

console.log(ret1)
console.log(ret2)
console.log(ret3)
console.log(ret4)
console.log(ret5)

 

* 연습과제 4

const comment = '너는 진짜 못말리는 바보 똥개 그지다 !'
const insults = ['바보', '똥개', '그지']

function separateStr(str, delimeter){
    let strSeparated = str.split(delimeter)
    function filterKeyword(keyword){
        strSeparated = strSeparated.filter(word => !word.includes(keyword))
        return strSeparated
    }
    return filterKeyword
}

const filterKeyword = separateStr(comment, ' ')

filterKeyword(insults[0]) // strSeparated 변수는 filterKeyword 함수 실행에 의해서만 변경이 가능함 (캡슐화, 은닉화) , 또한 내부에 저장되어 계속 업데이트됨
filterKeyword(insults[1])
console.log(filterKeyword(insults[2])) //

 

* 연습과제 5

const animals = ['cat', 'lion', 'turtle', 'dog', 'pig']
const fruits = ['apple', 'banana', 'strawberry', 'pineapple', 'pear']

function selectCategory(category){
    function searchItem(key){
        return category.filter(item => item === key)[0]
    }
    return searchItem
}

const searchAnimal = selectCategory(animals)
const searchFruit = selectCategory(fruits)

console.log(searchAnimal('turtle')) // searchAnimal 내부의 category 변수에는 접근하지 못하고 수정도 못함 (캡슐화, 은닉화)
console.log(searchAnimal('pig')) // 동물 카테고리에서만 검색한다는 함수의 역할이 명확히 드러남
console.log(searchAnimal('banana'))

console.log(searchFruit('strawberry')) // 서로 다른 기능을 하는 함수 생성
console.log(searchFruit('apple'))
console.log(searchFruit('lion'))

 

* 연습과제 6

const friends = [
    {name: 'victoria', age: 13, city: 'seoul'},
    {name: 'sun', age: 34, city: 'busan'},
    {name: 'johseb', age: 25, city: 'busan'},
    {name: 'syleemomo', age: 9, city: 'seoul'},
    {name: 'hannah', age: 41, city: 'daegu'},
    {name: 'shara', age: 37, city: 'seoul'},
    {name: 'martin', age: 28, city: 'daegu'},
    {name: 'gorgia', age: 39, city: 'seoul'},
    {name: 'nana', age: 24, city: 'busan'},
    {name: 'dannel', age: 19, city: 'seoul'},
]


function createPerson(name, age, city, friends){
    let _friends = JSON.parse(JSON.stringify(friends)) // 프라이빗 멤버변수를 보호하기 위하여 깊은복사로 저장함

    return {
        name, // 퍼블릭 멤버변수
        age,  // 퍼블릭 멤버변수
        city, // 퍼블릭 멤버변수

        get friends(){
            return JSON.parse(JSON.stringify(_friends)) // 프라이빗 변수를 보호하기 위하여 깊은복사로 조회함
        },
        filterFriendsInMyCity(){ 
            return this.friends.filter(friend => friend.city === this.city) 
        }
    }
}


const person = createPerson('영희', 23, 'daegu', friends)

console.log(person.friends === friends) // 전역변수 friends 와 프라이빗변수 _friends 주소가 다름을 확인함 (복사본을 저장하기 때문)
person.friends[0].name =  "태양" // 프라이빗 변수 _friends 를 변경하지 못함 (복사본을 조회하기 때문)

console.log(person.friends) 
console.log(person.filterFriendsInMyCity())

const person2 = createPerson('철수', 35, 'seoul', friends)
console.log(person2.friends) 
console.log(person2.filterFriendsInMyCity())

person2.name = "길동" // name 은 퍼블릭 멤버변수이므로 변경이 가능함
console.log(person2.name)

 

연습과제 7

const metadata = {
  title: "Scratchpad",
  translations: {
    info: {
      locale: "de",
      localization_tags: [],
      last_edit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
      time: {
        hour: 4
      }
    },
  },
  url: "/ko/docs/Tools/Scratchpad",
}

let d = 0
function findKeyOfObj(key, obj, depth){
  d++
  const keys = Object.keys(obj)
  if(keys.includes(key) && d == depth){
    d = 0
    return obj[key] 
  }
  for(let k of keys){
    // console.log(obj[k], typeof obj[k])
    if(typeof obj[k] === 'string' || typeof obj[k] === 'number' || typeof obj[k] === 'boolean' || Array.isArray(obj[k]) || obj[k] === null || obj[k] === undefined || obj[k] === ''){
      continue 
    }
    return findKeyOfObj(key, obj[k], depth)
  }
}

console.log(findKeyOfObj("title", metadata, 1))
console.log(findKeyOfObj("title", metadata, 3))

뎁스값을 기억하기 위하여 클로저를 사용하면 아래와 같다.

const metadata = {
  title: "Scratchpad",
  translations: {
    info: {
      locale: "de",
      localization_tags: [],
      last_edit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
      time: {
        hour: 4
      }
    },
  },
  url: "/ko/docs/Tools/Scratchpad",
}

function generateFindKeyFunc(){
  let d = 0
  function findKeyOfObj(key, obj, depth){
    d++
    const keys = Object.keys(obj)
    if(keys.includes(key) && d == depth){
      d = 0
      return obj[key] 
    }
    for(let k of keys){
      // console.log(obj[k], typeof obj[k])
      if(typeof obj[k] === 'string' || typeof obj[k] === 'number' || typeof obj[k] === 'boolean' || Array.isArray(obj[k]) || obj[k] === null || obj[k] === undefined || obj[k] === ''){
        continue 
      }
      return findKeyOfObj(key, obj[k], depth)
    }
  }
  return findKeyOfObj
}

const findKeyOfObj1 = generateFindKeyFunc()
const findKeyOfObj2 = generateFindKeyFunc()
const findKeyOfObj3 = generateFindKeyFunc()

console.log(findKeyOfObj1("title", metadata, 1))
console.log(findKeyOfObj2("title", metadata, 3))
console.log(findKeyOfObj3("hour", metadata, 4))

 

현재는 해당 뎁스에 동일한 키가 존재하는 경우 처음으로 검색되는 하나의 갑만 반환한다. 만약 해당 뎁스에 존재하는 동일한 키의 값을 모두 검색하려면 아래와 같이 하면 된다. 처음 클로저가 생성될때 빈 배열을 하나 정의하고, 키가 성공적으로 검색되면 키의 값을 배열에 담는다. 이때 주의할 점은 검색에 성공한 경우, return 하기 전에 현재 뎁스값을 1만큼 감소시켜줘야 다른 키도 계속 검색할 수 있다. 왜냐하면 return 하면서 재귀함수 밖으로 한번 빠져나가면 뎁스는 현재보다 1만큼 작기 때문이다. 

const metadata = {
  title: "Scratchpad",
  translations: {
    info: {
      locale: {
        hour: 9
      },
      localization_tags: {
        hour: "sunrise"
      },
      last_edit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
      time: {
        hour: 3
      }
    },
    version: {
      last_edit: "다른 버전"
    }
  },
  url: "/ko/docs/Tools/Scratchpad",
}

function generateFindKeyFunc(){
  let d = 0
  let foundValues = []
  function findKeyOfObj(key, obj, depth){
    d++
    const keys = Object.keys(obj)
    if(keys.includes(key) && d == depth){
      foundValues.push(obj[key])
      // console.log(foundValues)
      d--
      return foundValues
    }
    for(let k of keys){
      // console.log(obj[k], typeof obj[k])
      if(typeof obj[k] === 'string' || typeof obj[k] === 'number' || typeof obj[k] === 'boolean' || Array.isArray(obj[k]) || obj[k] === null || obj[k] === undefined || obj[k] === ''){
        continue 
      }
      // console.log(obj[k])
      // console.log(d)
      findKeyOfObj(key, obj[k], depth)
    }
    
    return foundValues
  }
  return findKeyOfObj
}

const findKeyOfObj1 = generateFindKeyFunc()
const findKeyOfObj2 = generateFindKeyFunc()
const findKeyOfObj3 = generateFindKeyFunc()
const findKeyOfObj4 = generateFindKeyFunc()

console.log(findKeyOfObj1("title", metadata, 1))
console.log(findKeyOfObj2("title", metadata, 3))
console.log(findKeyOfObj3("hour", metadata, 4))
console.log(findKeyOfObj4("last_edit", metadata, 3))
728x90