[코딩테스트/JS] 두 개 뽑아서 더하기

headerimg

두 개 뽑아서 더하기

문제 설명

정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.


제한 사항

  • numbers의 길이는 2 이상 100 이하입니다.
    • numbers의 모든 수는 0 이상 100 이하입니다.


입출력 예

numbersresult
[2,1,3,4,1][2,3,4,5,6,7]
[5,0,2,7][2,5,7,9,12]


입출력 예 설명

입출력 예 #1

  • 2 = 1 + 1 입니다. (1이 numbers에 두 개 있습니다.)
  • 3 = 2 + 1 입니다.
  • 4 = 1 + 3 입니다.
  • 5 = 1 + 4 = 2 + 3 입니다.
  • 6 = 2 + 4 입니다.
  • 7 = 3 + 4 입니다.
  • 따라서 [2,3,4,5,6,7]return 해야 합니다.

입출력 예 #2

  • 2 = 0 + 2 입니다.
  • 5 = 5 + 0 입니다.
  • 7 = 0 + 7 = 5 + 2 입니다.
  • 9 = 2 + 7 입니다.
  • 12 = 5 + 7 입니다.
  • 따라서 [2,5,7,9,12]return 해야 합니다.

내 솔루션

function solution(numbers) {
  return numbers.map((el, i) => {
    return numbers.map((el2, j) => (i < j) ? el+el2 : undefined)
  }).flat().sort((a,b)=>a-b).filter((n, i, arr)=> n !== arr[i-1] && n !== undefined);
}

감상평

오래전에 풀었던 문제인데, 압축하고 짧고 멋지게 만든다고 고생 했던 기억이 있다.
2중 for문 대신에 2중 map을 써봤다. 이때부터 map과 filter에 꼿혀있는게 느껴진다.
짧게 만드는 것이 결국엔 남이 읽기엔 좋은 코드는 아닐 수 도 있겠구나 싶다. ㅋㅋ

그렇게 따지만 어글리파이 하는게 최고겠지?

[Kidult] 국전에서 스누피, 포켓몬 테라리움과 마가이마가도 아미보

headerimg

오늘은 국전!

미토피아 발매일에 반차를 내고 미토피아 데모를 재미있게 했던 여자친구👫와 국전에 갔다!🎉
오랜만에 한우리에 갔더니 옆 매장에 확장을 해서 아미보나 여러가지 제품들과
라오어나 디비전2 같은 실물로 보기 힘들었던 한정판들도 보았다.

오늘의 득템은?

image image

포켓몬 테라리움에서 님피아, 피카츄, 어니부기 쪽을 원했지만. 식스테일! 쩨끔 아쉽


image image

추억속 스누피의 테라리움 5번!, 사실 2, 6번을 노렸지만 😭


image

그리고 대망의 여자친구가 사준 마가이마가도 아미보와 한컷! 📷


고정 작업을 해보자~

테라리움은 조립이 아니라 그냥 얹어 놓는 식이라 냅두면 세탁기 처럼 모든 부품이 돌아 댕긴다.
그래서 목공용 본드로 살짝 고정해주는 작업이 필요하닷

image

부품을 펼처 놓고


image image

엉덩이랑 나무 밑둥이랑 몬스터볼 바닥에 발라주었다.


image image

식스테일은 완성~ 준내 커엽따 슈밤.😍


image

스누피의 엉덩이와 핀 안쪽에 발라주고


image image

꼽아준 다음 5분 정도 기다려주었다.


image image

테이프를 잘 안보이는 곳에 발라줘 바닥이 따이지 않게 한다.


image image

유리병 같지만 플라스틱이고 뚜껑도 메탈같지만 플라스틱! 잘만들었구먼!


image

어흑.. 너무 이뻐 행복사😌


image

전시장으로 ㄱㄱㄱ


image

마가이는 생각보다 괜찮다.


image

오.. 눈빛.. 잘안보여


image

저 투명 기둥이 너무 무식하게 두꺼워서 살짝 아쉽..


너무 조아..

마가이마가도님 이 주시는 덧입기가 상당히 맘에들었지만 인터넷에 너무~ 비싸게 팔려서
아예 마음을 접었는데, 여친이 알아봐주고 사준 덕분에 너무 멋진 아미보와 덧입기 까지 얻게 되었다.

너무조아!!


테라리움도 개당 11000 ~ 12000원 짜리 뽑기라서 은근 비싸지만
케릭터들이 너무 커엽고 이쁘고 행복해보인다.

아늑한 테라리움 속에서 행복한 케릭터들을 보면
사회에서 닳고 닳은 힘든 내 맘속에 남아있는 작은 순수한 동심이 생각나서일까.
아주 보기 좋구만 기레👍

[React Hook] 01 - useState()

headerimg

REACT HOOK!

Hook은 React 버전 16.8부터 React 요소로 새로 추가되었습니다.
Hook을 이용하여 기존 Class 바탕의 코드를 작성할 필요 없이 상태 값과 여러 React의 기능을 사용할 수 있습니다.
얼마나 좋은지는 아래에 useState()를 보고 판단하자

React Functional Program을 하려면 Hook을 쓰자. 🙏

useState()

당신이 만약 버튼 2개로 이루어진 카운터 컴포넌트를 만든다고 가정하고
Class와 Hook으로 각각 만들어서 비교해보면 좋은지 안좋은지 알 것이다.

Class Counter

class CountClass extends React.Component {
  state = {
    count: 0,
  };
  increase() {
    this.setState((state) => {
      return { count: state.count + 1 };
    });
  }
  decrease() {
    this.setState((state) => {
      return { count: state.count - 1 };
    });
  }
  render() {
    return (
      <div className="countClass">
        <h1>Class</h1>
        <p>count : {this.state.count}</p>
        <button onClick={() => this.increase()}>증가</button>
        <button onClick={() => this.decrease()}>감소</button>
      </div>
    );
  }
}

좀더 줄일 수는 있지만 평범하게 만들자면 이런식으로
증가, 감소를 각각 함수로 빼주고 state.count를 변경한다.

Hook Counter

function CountHook() {
  // [0]번은 state 변수 이름, [1]은 값을 갱신하는 함수
  const [count, setCount] = useState(0); // 0은 초기 값
  const increase = () => setCount(count + 1); // 값을 갱신한다.
  const decrease = () => setCount(count - 1);
  return (
    <div className="countHook">
      <h1>Hook</h1>
      <p>count : {count}</p>
      <button onClick={increase}>증가</button>
      <button onClick={decrease}>감소</button>
    </div>
  );
}

😱 놀랍게도 거의 10줄에 끝나버렸다. 열받는 this도 없고 값을 변경하는 setState도 없어지니 이해하기도 한결 편하다. 물론 장점만 있는 것은 아니다… Closure가 찾아오기 전까진 조용히 재미있어하자.

[코딩테스트/JS] 기능개발

headerimg

기능개발

문제 설명

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다. 또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다. 먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.


제한 사항

  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.


입출력 예

progressesspeedsreturn
[93, 30, 55][1, 30, 5][2, 1]
[95, 90, 99, 99, 80, 99][1, 1, 1, 1, 1, 1][1, 3, 2]


입출력 예 설명

입출력 예 #1

첫 번째 기능은 93% 완료되어 있고 하루에 1%씩 작업이 가능하므로 7일간 작업 후 배포가 가능합니다. 두 번째 기능은 30%가 완료되어 있고 하루에 30%씩 작업이 가능하므로 3일간 작업 후 배포가 가능합니다. 하지만 이전 첫 번째 기능이 아직 완성된 상태가 아니기 때문에 첫 번째 기능이 배포되는 7일째 배포됩니다. 세 번째 기능은 55%가 완료되어 있고 하루에 5%씩 작업이 가능하므로 9일간 작업 후 배포가 가능합니다. 따라서 7일째에 2개의 기능, 9일째에 1개의 기능이 배포됩니다.

입출력 예 #2

모든 기능이 하루에 1%씩 작업이 가능하므로, 작업이 끝나기까지 남은 일수는 각각 5일, 10일, 1일, 1일, 20일, 1일입니다. 어떤 기능이 먼저 완성되었더라도 앞에 있는 모든 기능이 완성되지 않으면 배포가 불가능합니다.

따라서 5일째에 1개의 기능, 10일째에 3개의 기능, 20일째에 2개의 기능이 배포됩니다.

※ 공지 - 2020년 7월 14일 테스트케이스가 추가되었습니다.


내 솔루션

내가 푼 방식은 아래와 같다.

  • 각 진행도 [93, 30, 55]에서 남은양 / speeds = 남은 일을 구한다.
    • [7, 3, 9]로 만든다.
  • 여기서 각 배열의 [i], [i++]을 비교 할 때, [i] 보다 큰 수 가 나올때 까지 count를 올리고 그 수만큼 answer[]에 저장한다.
function solution(progresses, speeds) {
  const answer = [];
  
  // 남은 일 계산
  const days = progresses.map((el, idx) => Math.ceil((100 - el) / speeds[idx]));
  
  let maxDay = days[0];
  let count = 1;
  for(let i = 1; i < days.length+1 ; i++){
    // maxDay 보다 크거나, 마지막 순환일 땐 push한다.
    if(maxDay < days[i] || i === days.length){
      answer.push(count);
      maxDay = days[i];
      count = 1;
    } else {
      count++;
    }
  }
  return answer;
}

감상평

처음에 reduce나 map으로 하려다가 괜히 사서 고생했다. 재미있는 문제였음.

[코딩테스트/JS] 스킬트리

headerimg

스킬트리

문제 설명

선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.

예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.

위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.

선행 스킬 순서 skill과 유저들이 만든 스킬트리를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.

제한 조건

  • 스킬은 알파벳 대문자로 표기하며, 모든 문자열은 알파벳 대문자로만 이루어져 있습니다.
  • 스킬 순서와 스킬트리는 문자열로 표기합니다.
    • 예를 들어, C → B → D 라면 “CBD”로 표기합니다
  • 선행 스킬 순서 skill의 길이는 1 이상 26 이하이며, 스킬은 중복해 주어지지 않습니다.
  • skill_trees는 길이 1 이상 20 이하인 배열입니다.
  • skill_trees의 원소는 스킬을 나타내는 문자열입니다.
    • skill_trees의 원소는 길이가 2 이상 26 이하인 문자열이며, 스킬이 중복해 주어지지 않습니다.

입출력 예

skillskill_treesreturn
“CBD”[“BACDE”, “CBADF”, “AECB”, “BDA”]2

입출력 예 설명

  • “BACDE”: B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트립니다.
  • “CBADF”: 가능한 스킬트리입니다.
  • “AECB”: 가능한 스킬트리입니다.
  • “BDA”: B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트리입니다.

내 솔루션

내가 푼 방식은 아래와 같다.

  • ["BACDE", "CBADF", "AECB", "BDA"]에서 "CBD"와 매칭되는 글자를 해당 인덱스로 바꾼다.
    • ["102", "012", "01", "12"]
  • 이 숫자가 0부터 오름차순의 순서이면 true이다.
function solution(skill, skill_trees) {
  const skill_arr = skill.split('');
  return skill_trees.map(skill_tree => {
    // 스킬 트리 배열을 글자 단위로 자름.
    return skill_tree.split('') 
      .map(S => skill.split('').findIndex((el, i) => S === el)) 
      // 스킬트리의 글자와 스킬을 비교하여 찾은 인덱스를 리턴
      .filter(el=>el !== -1).map((e,i) => e === i).every(x=>x); 
      // 찾은 인덱스의 순서가 오름차순인지 검사함.
  }).filter(el => el).length; // 오름 차순으로 검사한 배열의 숫자를 셈
}

감상평

풀고 나니 startsWith이 있었던 것이 기억나더라 😪 다른 사람이 알아먹기도 힘들고 나 자신조차도 split('')한다고 정신 없었다. ㅋㅋ 다른 사람들 풀이를 보고 있자니 나는 뭔가 map, filter에 많이 꼿혀 있는 편인 것 같다.




최고의 솔루션

function solution(skill, skill_trees) {
    let regex = new RegExp(`[^${skill}]`, 'g'); // regex 활용법
    return skill_trees
        .map((x) => x.replace(regex, ''))
        .filter((x) => skill.startsWith(x)) // startsWith 기억해둘것
        .length
}
// 다른 사람 풀이에 조금 수정만 했다.
// skill.indexOf(x) === 0 로도 가능.

[book] 마션의 작가 최신작 프로젝트 헤일메리

headerimg

MD 한마디
[『마션』 작가가 선보이는 경이로운 우주 활극] 『프로젝트 헤일메리』는 멸망 위기의 지구를 구하기 위해 돌아올 수 없는 우주 출장을 떠난 과학자의 이야기다. 우주 한복판, 편도 우주선 ‘헤일메리’에서 살아남은 것은 주인공 한 명 뿐! 설상가상 외계인까지 등장하는데, 인류의 운명을 짊어진 그는 무사히 임무를 완수할 수 있을까? -소설MD 박형욱

점심시간 심심해서..

다이어트 겸 코로나 때문에 회사에서 샐러드만 시켜먹은지 2주 째!
1시간이라는 빡빡한 점심시간이 어느 순간 정신차리니 30분 정도가 남아버렸다.

매번 유투브나 보고 멍때리거나 산책을 했지만 더워지기 시작하고…

북마니또

작년 가을 쯤 회사에서 진행했던 북마니또가 생각났다.
각자 책을 추천하고 그 책을 추천했던 분들 맞추는 이벤트였다.

book_02

워낙 독서를 좋아해서 교보VIP까지 갔었지만… 점점 책값이 비싸지고
점점 집이 비좁아 지면서 등한시 했던 독서를 다시 시작하게 끔 해준 아주 고마운 이벤트였다.

book_03

내가 추천 했던 마션도 있다. ㅋㅋ

과학적으로 실현 가능한 SF장르의 책으로 도입부부터 아주 파격적인 시작을 합니다. 공기, 물, 음식 등 생존에 필요한 모든 필수 요소가 없어진 상황에서 주인공이 극복해나아가는 과정을 멋지고 소름돋게 표현합니다. -프론트엔드 개발자의 추천사

새로 나왔데!! 꺄 신상이야

퇴근 중에 신논현 교보문고 팝업 스토어에서 엔디 워어의 신작 책이 나온 것을 보고 오!! 했지만
책 가격이 무슨 18,500원!! 1책 === 1치킨?? 그래서 그냥 에이~ 안사 하면서 돌아 갔지만

YES24에서 10%할인이랑 맥주잔도 준다고? 좋아 산다 하며 바로 다음날 사버림

book_01

표지 디자인이 아주 아주 영롱하다.

book_00

책갈피로 주는 우주선 티켓도 아주 맘에 들고 맥주잔도 아주 맘에 쏙 들었다.

그래서 어떤데?

점심 시간에 1챕터를 읽었는데, 마션 초반에 느낄 수 있었던 아 슈발 좆됨.의 아주 좋은 시작이다.
번역이 약간 올..드 하긴 한데 이건 나중에 자세히 다룰 예정..

아직까진 나쁘지 않아

[코딩테스트/JS] 멀쩡한 사각

headerimg

멀쩡한 사각

문제 설명

가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을 따라 1cm × 1cm의 정사각형으로 잘라 사용할 예정이었는데, 누군가가 이 종이를 대각선 꼭지점 2개를 잇는 방향으로 잘라 놓았습니다. 그러므로 현재 직사각형 종이는 크기가 같은 직각삼각형 2개로 나누어진 상태입니다. 새로운 종이를 구할 수 없는 상태이기 때문에, 이 종이에서 원래 종이의 가로, 세로 방향과 평행하게 1cm × 1cm로 잘라 사용할 수 있는 만큼만 사용하기로 하였습니다. 가로의 길이 W와 세로의 길이 H가 주어질 때, 사용할 수 있는 정사각형의 개수를 구하는 solution 함수를 완성해 주세요.

제한 사항

W, H : 1억 이하의 자연수

입출력 예

WHresult
81280

입출력 예 설명

가로가 8, 세로가 12인 직사각형을 대각선 방향으로 자르면 총 16개 정사각형을 사용할 수 없게 됩니다. 원래 직사각형에서는 96개의 정사각형을 만들 수 있었으므로, 96 - 16 = 80 을 반환합니다.


솔루션

function solution(width, hight) {
  let w = width;
  let h = hight;
  let GCDs = [];
  
  let divider = 2;
  while(divider <= w && divider <= h){
    if(w % divider === 0 && h % divider === 0){
      w = w/divider;
      h = h/divider;
      GCDs.push(divider);
      divider = 1;
    }
    divider++;
  }
  
  return (width * hight) - (width + hight - GCDs.reduce((a,b) => a * b, 1));
}
const t1 = solution(8, 12);
console.log(t1);


감상평

총사각형의수 - (w + h - (w와 h의 최대공약수))가 정답이라는 식을 알아내는데 시간이 많이 들었다. 만약에 실제 코딩테스트에 만났다면 이 문제는 포기했을 가능성이 높다. 어릴 때, 소인수분해 하던 것이 떠올라 이 방식으로 문제를 풀었고 최대공약수를 구하는 간단한 유클리드 호제법이라는게 있는 것은 알았지만 공식이 떠오르지 않아 포기ㅠ

//최대공약수를 구하는 간단한 재귀함수
function gcd (a, b) {
	return !b ? a : gcd( b, a % b )
}

[코딩테스트/JS] 다트 게임

headerimg

다트 게임

문제 설명

카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다. 다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다. 갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다. 다트 게임의 점수 계산 로직은 아래와 같다.

  1. 다트 게임은 총 3번의 기회로 구성된다.
  2. 각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.
  3. 점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시 점수에서 1제곱, 2제곱, 3제곱 (점수1 , 점수2 , 점수3 )으로 계산된다.
  4. 옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.
  5. 스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)
  6. 스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)
  7. 스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)
  8. Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.
  9. 스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.

    0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.

입력 형식

“점수|보너스|[옵션]”으로 이루어진 문자열 3세트. 예) 1S2D*3T

점수는 0에서 10 사이의 정수이다. 보너스는 S, D, T 중 하나이다. 옵선은 *이나 # 중 하나이며, 없을 수도 있다.

출력 형식

3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다. 예) 37

예제dartResultanswer설명
11S2D*3T3711 * 2 + 22 * 2 + 33
21D2S#10S912 + 21 * (-1) + 101
31D2S0T312 + 21 + 03
41S*2T*3S2311 * 2 * 2 + 23 * 2 + 31
51D#2S*3S512 * (-1) * 2 + 21 * 2 + 31
61T2D3D#-413 + 22 + 32 * (-1)
71D2S3T*5912 + 21 * 2 + 33 * 2



솔루션

const splitStr = function(str){
    let strArr = str.split(/([0-9]{1,2}[S|D|T][#,*]?)/gi).filter(s => s !== '');
    return strArr.map((str) => {
       return str.split(/([0-9]{1,2}|[S|D|T]|[#,*]?)/).filter(s => s !== '');
    })
}

const BONUSES = { S: 1, D: 2, T: 3};
const OPTIONS = { '*': 2, '#': -1, 'Null': 1};

function solution(dartResult) {
    if(!dartResult) return;
    let answer = [];
    
    splitStr(dartResult).forEach((inputVal, i)=>{
      const score = Number(inputVal[0]);
      const bonus = inputVal[1];
      const option = inputVal[2] || 'Null';
      
      if(option==='*') answer[i-1] = answer[i-1] * OPTIONS[option];

      answer.push( (score ** BONUSES[bonus]) * OPTIONS[option] );
    })
    return answer.reduce((a, b) => a + b, 0);
}

감상평

푼지 오래된 녀석이라 코드를 대부분 잊어버려서 내 코드를 찬찬히 훑어보았다. splitStr()를 통해서 입력된 문자열을 풀고 하나하나 계산 때리는 방식이다. 짧게 쓰려고 압축하지 않아서 그런지 이해는 빠르고 쉽게 되었다. split에 있는 정규표현식을 재활용 했다면 더 좋았을 뜻하다.

[DEV] 04 - map (함수형프로그래밍 es06)

headerimg
함수형 프로그래밍과 javascript es6를 깊게 파보기.


map

Array.prototype.map()과 비슷한 map()이라는 함수를 만들어 이터레이션 프로토콜에 좀더 대해 느껴보자.

const products = [
  {name: '반팔티', price: 15000},
  {name: '긴팔티', price: 20000},
  {name: '핸드폰케이스', price: 15000},
  {name: '후드티', price: 30000},
  {name: '바지', price: 25000}
];

// Array.protortype.map() 보단 간단하지만 비슷한 일을한다.
const map = (func, iter) => {
  // 인자로 함수와, 이터러블을 받는다.
  let res = [];
  for(const a of iter){
    // 인자로 들어온 func()함수를 실행후 값을 res에 push한다.
    res.push(func(a));
  }
  // 만들어진 배열을 반환한다.
  return res;
}
/*
원래의 Array.prototype.map()은 인자값을 체크하고 iterable의 길이를 체크하는 등. 
훨신 더 복잡하다
*/

// name 
let names = map(p => p.name, products);
console.log(names)

// 특히 이 map 함수는 이터레이션 프로토콜을 따르기 때문에 nodeList에도 사용할 수 있다.


진짜 map 함수

let arr = [1,4,9];
let t1 = arr.map(a => a + 1); // [2, 5, 10];
let t2 = arr.map(Math.sqrt);  // [1, 2, 3];
console.log(arr); // [1, 4, 9]

mapcallback함수를 각각 요소에 대해 한번씩 순서대로 불러오고 그 함수들의 반환 값으로 새로운 배열을 만든다. Array.prototype.map()이다.

const products = [
  {name: '반팔티', price: 15000},
  {name: '긴팔티', price: 20000},
  {name: '핸드폰케이스', price: 15000},
  {name: '후드티', price: 30000},
  {name: '바지', price: 25000}
];

let reformatted = products.map((obj)=>{
  let newObj = {};
  newObj[obj.name] = obj.price;
  return newObj;
});
console.log(reformatted);

![imgG](/assets/img/post/functional/Screenshot_3.png){:.center}

var map = Array.prototype.map;
var a = map.call('Hello World', function(x) { return x.charCodeAt(0); });
// a는 이제 [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
dataSet.map(function)
dataSet.map.call(dataSet, function)
[].map.call(dataSet, function)
Array.prototype.map.call(dataSet, function)

[DEV] 03 - 제너레이터 (함수형프로그래밍 es06)

headerimg
함수형 프로그래밍과 javascript es6를 깊게 파보기.


제너레이터(Generator)

  • 제너레이터: 이터레이터이자 이터러블을 생성하는 함수. function* 선언 (끝에 별표가 있는 function keyword) 은 generator function 을 정의하는데, 이 함수는 Generator 객체를 반환합니다.(by MDN)
    Generator 객체는 generator function 으로부터 반환된 값이며 반복자와 반복자 프로토콜을 준수합니다.(by MDN)
function* generator(i) {
  // 1번째 호출.
  yield i; 
  
  // 2번째 호출
  yield i + 10;

  // 마지막 호출
  return i * 10; 
}

const iter = generator(10);

// 이터레이터이자 이터러블이다.
console.log(iter[Symbol.iterator]() === iter); // true

console.log(iter.next().value); // 10
console.log(iter.next().value); // 20
console.log(iter.next().value); // 100
console.log(iter.next()); // { value: undefined, done: true}

// for-of 호출 시 return은 호출되지 않는다.
for(const v of gen(1)) console.log(a);
// 1
// 11

제너레이터 객체는 이터레이션 프로토콜을 따르기 때문에 순회할 수 있다.


제너레이터 예제

하나씩 천천히 따라 해보면 뭔가 감이 싹 온다.

// 무한 숫자
function *infinity(i = 0){
    while(true) yield i++;
}

const iter = infinity(1);

console.log(iter.next().value); // 1
console.log(iter.next().value); // 2
console.log(iter.next().value); // 3
console.log(iter.next().value); // 4


짝수 홀수 가져오기


// 무한 숫자 제너레이터
function* infinity(i = 0){
    while(true) yield i++;
}

// 짝 홀 제너레이터
function *oddEven(oddEven = 0){
  for(n of infinity(1)){
    if(n % 2 === oddEven) yield n;
  }
}
const iter = oddEven(0);

console.log(iter.next().value); // 2
console.log(iter.next().value); // 4
console.log(iter.next().value); // 6
console.log(iter.next().value); // 8


원하는 숫자만큼 가져오기

// 무한 숫자 제너레이터
function* infinity(i = 0){
    while(true) yield i++;
}

// 제한 숫자 정해놓기
function* limit(limitNum, iter){
  for(const v of iter){
    yield v;
    if(v === limitNum) return;
  }
}

// 짝 홀 제너레이터
function* oddEven(oddEven = 0, limitNum){
  for(const n of limit(limitNum, infinity(1))){
    if(n % 2 === oddEven) yield n;
  }
}

for(const a of oddEven(1, 10)) console.log(a);

// 1
// 3
// 5
// 7
// 9


for-of, 전개 연산자, 구조 분해, 나머지 연산자

끼워 넣기

console.log(...oddEven(1, 10));
// 1,3,5,7,9

console.log([...oddEven(0, 10), ...oddEven(1, 10)])
// [2, 4, 6, 8, 10, 1, 3, 5, 7, 9]

const [head, ...body] = oddEven(0, 10);
console.log(head, body)
// 2 [4, 6, 8, 10]

Pagination


© 2018. All rights reserved.