<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>star-ho.log</title>
        <link>https://velog.io/</link>
        <description>개발!</description>
        <lastBuildDate>Tue, 30 Mar 2021 08:37:06 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>star-ho.log</title>
            <url>https://images.velog.io/images/star-ho/profile/3877119d-0e0a-43ba-87e3-1a69a5a61a91/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. star-ho.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/star-ho" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[팰린드롬 찾기]]></title>
            <link>https://velog.io/@star-ho/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@star-ho/%ED%8C%B0%EB%A6%B0%EB%93%9C%EB%A1%AC-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Tue, 30 Mar 2021 08:37:06 GMT</pubDate>
            <description><![CDATA[<p>팰린드롬이란 문자열을 거꾸로 읽어도 제대로 읽은것과 같은 문자열을 의미한다.</p>
<pre><code>function isPalindrome(str){
    for(let i=0;i&lt;str.length/2;i++){
        if(str[i]!=str[str.length-i-1])
            return false
    }
    return true
}
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Docker file 및 Docker-compose작성]]></title>
            <link>https://velog.io/@star-ho/Docker-file-%EB%B0%8F-Docker-compose%EC%9E%91%EC%84%B1</link>
            <guid>https://velog.io/@star-ho/Docker-file-%EB%B0%8F-Docker-compose%EC%9E%91%EC%84%B1</guid>
            <pubDate>Mon, 29 Mar 2021 14:05:05 GMT</pubDate>
            <description><![CDATA[<pre><code>FROM node:13.7 #이미지 불러오기

WORKDIR /app #디렉토리 변경
COPY . /app # 소스코드 이동

RUN npm install #필요한 패키지 설치

RUN npm i -g @nestjs/cli

RUN npm install @nestjs/typeorm typeorm mysql2 @types/redis redis  express-session express-mysql-session

RUN npm install --save @nestjs/passport passport passport-local @types/passport-local @nestjs/jwt passport-jwt @types/passport-jwt


CMD [ &quot;npm&quot;, &quot;run&quot;, &quot;start:dev&quot; ] #이미지를 컨테이너화 시킬때 명령</code></pre><pre><code>version: &#39;3&#39;
services:
  app:
    container_name: starho
    build: .
    ports:
      - &#39;3000:3000&#39;
    depends_on: #특정 컨테이너에 대한 의존 관계를 나타냄, 
      - db #이 항목에 명시된 컨테이너가 먼저 생성되고 실행됩니다. 

  db: # 서비스 명
    image: mysql:8.0.15 # 사용할 이미지
    container_name: db # 컨테이너 이름 설정
    ports:
      - &quot;3306:3306&quot; # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
    environment: # -e 옵션
      MYSQL_ROOT_PASSWORD: &quot;boardjs&quot;  # MYSQL 패스워드 설정 옵션
      MYSQL_DATABASE: &quot;board_api&quot;
      MYSQL_USER: &#39;node&#39;
      MYSQL_PASSWORD: &#39;boardjs&#39;
    command: # 명령어 실행
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci    
      - --default-authentication-plugin=mysql_native_password

</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[1로 구성된 submatrix 합 구하기]]></title>
            <link>https://velog.io/@star-ho/1%EB%A1%9C-%EA%B5%AC%EC%84%B1%EB%90%9C-submatrix-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@star-ho/1%EB%A1%9C-%EA%B5%AC%EC%84%B1%EB%90%9C-submatrix-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 27 Mar 2021 01:39:05 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/star-ho/post/65010155-ab78-4c8c-93bf-c7c75f05a0fa/image.png" alt=""></p>
<p>1로 구성된 submatrix란 위 그림에서 빨간색으로 표시해놓은 1로 구성된 행렬을 의미한다.</p>
<p>submatrix의 합을 구하는 방법은 아래 코드와 같다</p>
<pre><code>var countSquares = function(matrix) {
    let row = matrix.length;
    let column = matrix[0].length;

    for(let i=1;i&lt;row;i++) {//(*)
        for(let j=1;j&lt;column;j++) {
            if(matrix[i][j] &amp;&amp; matrix[i-1][j] &amp;&amp; matrix[i][j-1] &amp;&amp; matrix[i-1][j - 1]) {
                matrix[i][j] = Math.min(matrix[i-1][j - 1], matrix[i][j-1], matrix[i-1][j]) + 1;
            }
        }
    }
    let sum = 0;

    for(let i=0;i&lt;row;i++) {
        sum += matrix[i].reduce((a,b) =&gt; a + b, 0);
    }

    return sum;
};</code></pre><p> (*)표시된 반복문이 핵심이니 이부분만 설명한다.
 [1,1]부터 시작해서 [1,1]&#39;(현재위치), [0,1]&#39;(위), [1,0]&#39;(왼쪽), [0,0]&#39;(왼쪽위)이 모두 0이 아니면 [0,1], [1,0], [0,0]의 최소값+1을 반환한다.</p>
<p> <img src="https://images.velog.io/images/star-ho/post/35bdfe5c-2414-4458-90b5-de0ce5d72c32/image.png" alt=""></p>
<p>참고
<a href="https://leetcode.com/problems/count-square-submatrices-with-all-ones/discuss/643329/Javascript-solution">https://leetcode.com/problems/count-square-submatrices-with-all-ones/discuss/643329/Javascript-solution</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[범위 수 계산]]></title>
            <link>https://velog.io/@star-ho/%EB%B2%94%EC%9C%84-%EC%88%98-%EA%B3%84%EC%82%B0</link>
            <guid>https://velog.io/@star-ho/%EB%B2%94%EC%9C%84-%EC%88%98-%EA%B3%84%EC%82%B0</guid>
            <pubDate>Sat, 27 Mar 2021 00:39:00 GMT</pubDate>
            <description><![CDATA[<p>1부터 n까지 계산시 
<img src="https://images.velog.io/images/star-ho/post/be32b8dd-7321-475b-9d62-dfe348818f9f/image.png" alt="">
로 계산가능</p>
<p>i에서 j까지의 합 계산시에는 (1부터 i까지의 합) - (1부터 j까지의 합)</p>
<p>중학교 수학인거 같은데... 무턱대고 반복문을 돌렸다
생각하며 풀자!</p>
<pre><code>    let rangesum=(i,j)=&gt;{
        return ((j*((j+1))/2)-(i*(i+1)/2))
    }</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 이분탐색 알고리즘]]></title>
            <link>https://velog.io/@star-ho/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9D%B4%EB%B6%84%ED%83%90%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@star-ho/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9D%B4%EB%B6%84%ED%83%90%EC%83%89-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Mon, 22 Mar 2021 11:57:35 GMT</pubDate>
            <description><![CDATA[<p>아래 코드는 d2라이브러리의 bisect함수를 따온것이다.</p>
<p>d2라이브러리를 사용하는 것이 좋지만, 코딩테스트에서 d2라이브러리를 사용 못하는 상황에서 유용할것이다.</p>
<p>사용예</p>
<pre><code>let arr=[1,2,3,4,5]


console.log(bysect.left(arr,3))//2
</code></pre><p>bysect코드</p>
<pre><code>var bysect=bisector(ascending)

function bisector(f) {
    let delta = f;
    let compare = f;

    if (f.length === 1) {
      delta = (d, x) =&gt; f(d) - x;
      compare = ascendingComparator(f);
    }

    function left(a, x, lo, hi) {
      if (lo == null) lo = 0;
      if (hi == null) hi = a.length;
      while (lo &lt; hi) {
        const mid = (lo + hi) &gt;&gt;&gt; 1;
        if (compare(a[mid], x) &lt; 0) lo = mid + 1;
        else hi = mid;
      }
      return lo;
    }

    function right(a, x, lo, hi) {
      if (lo == null) lo = 0;
      if (hi == null) hi = a.length;
      while (lo &lt; hi) {
        const mid = (lo + hi) &gt;&gt;&gt; 1;
        if (compare(a[mid], x) &gt; 0) hi = mid;
        else lo = mid + 1;
      }
      return lo;
    }

    function center(a, x, lo, hi) {
      if (lo == null) lo = 0;
      if (hi == null) hi = a.length;
      const i = left(a, x, lo, hi - 1);
      return i &gt; lo &amp;&amp; delta(a[i - 1], x) &gt; -delta(a[i], x) ? i - 1 : i;
    }

    return {left, center, right};
}



function ascending(a, b) {
    return a &lt; b ? -1 : a &gt; b ? 1 : a &gt;= b ? 0 : NaN;
  }</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[2차원 배열 돌리기]]></title>
            <link>https://velog.io/@star-ho/2%EC%B0%A8%EC%9B%90-%EB%B0%B0%EC%97%B4-%EB%8F%8C%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@star-ho/2%EC%B0%A8%EC%9B%90-%EB%B0%B0%EC%97%B4-%EB%8F%8C%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Sun, 21 Mar 2021 08:02:37 GMT</pubDate>
            <description><![CDATA[<p>*<em>시계 방향으로 돌리기
*</em></p>
<pre><code>console.log(board)
function rotateRigth(arr){
    let n=arr[0].length
    let m=arr.length
    let result=Array.from({length:n},()=&gt;Array.from({length:m},()=&gt;0))
    result.forEach((_,i)=&gt;{
            _.forEach((v,j)=&gt;{
                result[i][j]=arr[m-j-1][i]
            })
    })
    return result
}
console.log(rotateRigth(board))    </code></pre><p><strong>board</strong></p>
<pre><code>[
  [ &#39;C&#39;, &#39;C&#39;, &#39;B&#39;, &#39;D&#39;, &#39;E&#39; ],
  [ &#39;A&#39;, &#39;A&#39;, &#39;A&#39;, &#39;D&#39;, &#39;E&#39; ],
  [ &#39;A&#39;, &#39;A&#39;, &#39;A&#39;, &#39;B&#39;, &#39;F&#39; ],
  [ &#39;C&#39;, &#39;C&#39;, &#39;B&#39;, &#39;B&#39;, &#39;F&#39; ]
]</code></pre><p><strong>result</strong></p>
<pre><code>[
  [ &#39;C&#39;, &#39;A&#39;, &#39;A&#39;, &#39;C&#39; ],
  [ &#39;C&#39;, &#39;A&#39;, &#39;A&#39;, &#39;C&#39; ],
  [ &#39;B&#39;, &#39;A&#39;, &#39;A&#39;, &#39;B&#39; ],
  [ &#39;B&#39;, &#39;B&#39;, &#39;D&#39;, &#39;D&#39; ],
  [ &#39;F&#39;, &#39;F&#39;, &#39;E&#39;, &#39;E&#39; ]
]</code></pre><p>*<em>반시계방향으로 돌리기
*</em></p>
<pre><code>console.log(board)
function rotateLeft(arr){
    let n=arr[0].length
    let m=arr.length
    let result=Array.from({length:n},()=&gt;Array.from({length:m},()=&gt;0))
    result.forEach((_,i)=&gt;{
            _.forEach((v,j)=&gt;{
                result[i][j]=arr[j][m-i]
            })
    })
    return result
}
console.log(rotateLeft(board))      </code></pre><p><strong>board</strong></p>
<pre><code>[
  [ &#39;C&#39;, &#39;C&#39;, &#39;B&#39;, &#39;D&#39;, &#39;E&#39; ],
  [ &#39;A&#39;, &#39;A&#39;, &#39;A&#39;, &#39;D&#39;, &#39;E&#39; ],
  [ &#39;A&#39;, &#39;A&#39;, &#39;A&#39;, &#39;B&#39;, &#39;F&#39; ],
  [ &#39;C&#39;, &#39;C&#39;, &#39;B&#39;, &#39;B&#39;, &#39;F&#39; ]
]</code></pre><p><strong>result</strong></p>
<pre><code>[
  [ &#39;E&#39;, &#39;E&#39;, &#39;F&#39;, &#39;F&#39; ],
  [ &#39;D&#39;, &#39;D&#39;, &#39;B&#39;, &#39;B&#39; ],
  [ &#39;B&#39;, &#39;A&#39;, &#39;A&#39;, &#39;B&#39; ],
  [ &#39;C&#39;, &#39;A&#39;, &#39;A&#39;, &#39;C&#39; ],
  [ &#39;C&#39;, &#39;A&#39;, &#39;A&#39;, &#39;C&#39; ]
]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[javascript 관련 함수]]></title>
            <link>https://velog.io/@star-ho/javascript-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@star-ho/javascript-%EA%B4%80%EB%A0%A8-%ED%95%A8%EC%88%98</guid>
            <pubDate>Sat, 20 Mar 2021 15:40:16 GMT</pubDate>
            <description><![CDATA[<p>compact
false,null,0,””빼고 다 반환</p>
<pre><code>//_.compact(array)
_.compact([0, 1, false, 2, &#39;&#39;, 3]);
=&gt; [1, 2, 3]</code></pre><p>without
value값을 제외한 나머지값을 리턴</p>
<pre><code>//_.without(array, *values)
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
=&gt; [2, 3, 4]</code></pre><p>union
전달 된 모든 배열의 각 개별 요소의 집합을 포함하는 배열을 제공한다.</p>
<pre><code>//_.union(*arrays)
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=&gt; [1, 2, 3, 101, 10]</code></pre><p>intersection
교집합</p>
<pre><code>//_.intersection(*arrays)
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=&gt; [1, 2]</code></pre><p>difference
차집합</p>
<pre><code>//_.difference(array, *others)
_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=&gt; [1, 3, 4]</code></pre><p>zip
서로 상응하는 값끼리 묶어준다</p>
<pre><code>//_.zip(*arrays)
_.zip([&#39;moe&#39;, &#39;larry&#39;, &#39;curly&#39;], [30, 40, 50], [true, false, false]);
=&gt; [[&quot;moe&quot;, 30, true], [&quot;larry&quot;, 40, false], [&quot;curly&quot;, 50, false]]</code></pre><p>unzip
zip의 반대개념</p>
<pre><code>//_.unzip(array)
_.unzip([[&quot;moe&quot;, 30, true], [&quot;larry&quot;, 40, false], [&quot;curly&quot;, 50, false]]);
=&gt; [[&#39;moe&#39;, &#39;larry&#39;, &#39;curly&#39;], [30, 40, 50], [true, false, fals</code></pre><p>where
list의 각 value에서
리스트에서 key-value값이 맞는 모든 properties를 반환</p>
<pre><code>//_.where(list, properties)
_.where(listOfPlays, {author: &quot;Shakespeare&quot;, year: 1611});
=&gt; [{title: &quot;Cymbeline&quot;, author: &quot;Shakespeare&quot;, year: 1611},
    {title: &quot;The Tempest&quot;, author: &quot;Shakespeare&quot;, year: 1611}]</code></pre><p>every
list내 모든게 참이여야 true를 반환
되도록 ES5 filter를 쓰도록하자.</p>
<pre><code>//_.every(list, [predicate], [context])
_.every([2, 4, 5], function(num) { return num % 2 == 0; });
=&gt; false</code></pre><p>some
하나라도 참이면 true!</p>
<pre><code>//_.some(list, [predicate], [context])
_.some([null, 0, &#39;yes&#39;, false]);
=&gt; true</code></pre><p>sortBy
sorting 용</p>
<pre><code>//_.sortBy(list, iteratee, [context])
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); });
=&gt; [5, 4, 6, 3, 1, 2]

var stooges = [{name: &#39;moe&#39;, age: 40}, {name: &#39;larry&#39;, age: 50}, {name: &#39;curly&#39;, age: 60}];
_.sortBy(stooges, &#39;name&#39;);
=&gt; [{name: &#39;curly&#39;, age: 60}, {name: &#39;larry&#39;, age: 50}, {name: &#39;moe&#39;, age: 40}];</code></pre><p>groupBy
리턴값이 같은것끼리 array로 묶음</p>
<pre><code>//_.groupBy(list, iteratee, [context])
_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); });
=&gt; {1: [1.3], 2: [2.1, 2.4]}

_.groupBy([&#39;one&#39;, &#39;two&#39;, &#39;three&#39;], &#39;length&#39;);
=&gt; {3: [&quot;one&quot;, &quot;two&quot;], 5: [&quot;three&quot;]}</code></pre><p>indexBy
배열들을 index값을 기준으로 mapping</p>
<pre><code>//_.indexBy(list, iteratee, [context])
var stooges = [{name: &#39;moe&#39;, age: 40}, {name: &#39;larry&#39;, age: 50}, {name: &#39;curly&#39;, age: 60}];
_.indexBy(stooges, &#39;age&#39;);
=&gt; {
  &quot;40&quot;: {name: &#39;moe&#39;, age: 40},
  &quot;50&quot;: {name: &#39;larry&#39;, age: 50},
  &quot;60&quot;: {name: &#39;curly&#39;, age: 60}
}</code></pre><p><a href="https://harrythegreat.tistory.com/entry/%EC%96%B8%EB%8D%94%EC%8A%A4%EC%BD%94%EC%96%B4-%EC%A0%95%EB%A6%AC">https://harrythegreat.tistory.com/entry/%EC%96%B8%EB%8D%94%EC%8A%A4%EC%BD%94%EC%96%B4-%EC%A0%95%EB%A6%AC</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[객체 프로퍼티]]></title>
            <link>https://velog.io/@star-ho/%EA%B0%9D%EC%B2%B4-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0</link>
            <guid>https://velog.io/@star-ho/%EA%B0%9D%EC%B2%B4-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0</guid>
            <pubDate>Sat, 20 Mar 2021 15:36:26 GMT</pubDate>
            <description><![CDATA[<p>객체 프로퍼티는 값(value) 과 함께 플래그(flag)라 불리는 특별한 속성 세 가지를 가짐</p>
<p>writable – true이면 값을 수정할 수 있습니다. 그렇지 않다면 읽기만 가능합니다.
enumerable – true이면 반복문을 사용해 나열할 수 있습니다. 그렇지 않다면 반복문을 사용해 나열할 수 없습니다.
configurable – true이면 프로퍼티 삭제나 플래그 수정이 가능합니다. 그렇지 않다면 프로퍼티 삭제와 플래그 수정이 불가능합니다.</p>
<pre><code>let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);</code></pre><p>obj
정보를 얻고자 하는 객체
propertyName
정보를 얻고자 하는 객체 내 프로퍼티</p>
<pre><code>let user = {
  name: &quot;John&quot;
};

let descriptor = Object.getOwnPropertyDescriptor(user, &#39;name&#39;);

alert( JSON.stringify(descriptor, null, 2 ) );
/* property descriptor:
{
  &quot;value&quot;: &quot;John&quot;,
  &quot;writable&quot;: true,
  &quot;enumerable&quot;: true,
  &quot;configurable&quot;: true
}
*/</code></pre><p>Object.defineProperty
플래그를 변경</p>
<pre><code>Object.defineProperty(obj, propertyName, descriptor)</code></pre><p>obj, propertyName
설명자를 적용하고 싶은 객체와 객체 프로퍼티
descriptor
적용하고자 하는 프로퍼티 설명자</p>
<pre><code>let user = {};

Object.defineProperty(user, &quot;name&quot;, {
  value: &quot;John&quot;
});

let descriptor = Object.getOwnPropertyDescriptor(user, &#39;name&#39;);

alert( JSON.stringify(descriptor, null, 2 ) );
/*
{
  &quot;value&quot;: &quot;John&quot;,
  &quot;writable&quot;: false,
  &quot;enumerable&quot;: false,
  &quot;configurable&quot;: false
}
 */</code></pre><p> Object.defineProperties
 프로퍼티 여러 개를 한 번에 정의</p>
<pre><code> Object.defineProperties(obj, {
  prop1: descriptor1,
  prop2: descriptor2
  // ...
});


Object.defineProperties(user, {
  name: { value: &quot;John&quot;, writable: false },
  surname: { value: &quot;Smith&quot;, writable: false },
  // ...
});</code></pre><p>Object.getOwnPropertyDescriptors
프로퍼티 설명자를 전부 한꺼번에 가져옴</p>
<p>getter와 setter</p>
<pre><code>let obj = {
  get propName() {
    // getter, obj.propName을 실행할 때 실행되는 코드
  },

  set propName(value) {
    // setter, obj.propName = value를 실행할 때 실행되는 코드
  }
};</code></pre><p>예시</p>
<pre><code>let user = {
  name: &quot;John&quot;,
  surname: &quot;Smith&quot;,

  get fullName() {
    return `${this.name} ${this.surname}`;
  },

  set fullName(value) {
    [this.name, this.surname] = value.split(&quot; &quot;);
  }
};

// 주어진 값을 사용해 set fullName이 실행됩니다.
user.fullName = &quot;Alice Cooper&quot;;

alert(user.name); // Alice
alert(user.surname); // Cooper</code></pre><p>접근자 프로퍼티 설명자
get – 인수가 없는 함수로, 프로퍼티를 읽을 때 동작함
set – 인수가 하나인 함수로, 프로퍼티에 값을 쓸 때 호출됨
enumerable – 데이터 프로퍼티와 동일함
configurable – 데이터 프로퍼티와 동일함</p>
<p>접근자 프로퍼티 예시</p>
<pre><code>let user = {
  name: &quot;John&quot;,
  surname: &quot;Smith&quot;
};

Object.defineProperty(user, &#39;fullName&#39;, {
  get() {
    return `${this.name} ${this.surname}`;
  },

  set(value) {
    [this.name, this.surname] = value.split(&quot; &quot;);
  }
});

alert(user.fullName); // John Smith

for(let key in user) alert(key); // name, surname</code></pre><p>한 프로퍼티에 get과 value를 동시에 설정하면 에러가 발생</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[iterable 객체]]></title>
            <link>https://velog.io/@star-ho/iterable-%EA%B0%9D%EC%B2%B4-0bog8z3n</link>
            <guid>https://velog.io/@star-ho/iterable-%EA%B0%9D%EC%B2%B4-0bog8z3n</guid>
            <pubDate>Sat, 20 Mar 2021 15:35:19 GMT</pubDate>
            <description><![CDATA[<p><strong>배열을 일반화한 객체</strong>
iterable 객체는 for..of 반복문 적용 가능</p>
<p><strong>Symbol.iterator</strong>
Symbol.iterator객체가 존재한다면 for..of적용 가능</p>
<pre><code>let range = {
  from: 1,
  to: 5
};

// 1. for..of 최초 호출 시, Symbol.iterator가 호출됩니다.
range[Symbol.iterator] = function() {

  // Symbol.iterator는 이터레이터 객체를 반환합니다.
  // 2. 이후 for..of는 반환된 이터레이터 객체만을 대상으로 동작하는데, 이때 다음 값도 정해집니다.
  return {
    current: this.from,
    last: this.to,

    // 3. for..of 반복문에 의해 반복마다 next()가 호출됩니다.
    next() {
      // 4. next()는 값을 객체 {done:.., value :...}형태로 반환해야 합니다.
      if (this.current &lt;= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  };
};

// 이제 의도한 대로 동작합니다!
for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5</code></pre><p><strong>range를 for..of호출 시 발생하는 일</strong></p>
<ol>
<li>for..of가 시작되자마자 for..of는 Symbol.iterator를 호출합니다(Symbol.iterator가 없으면 에러가 발생합니다). Symbol.iterator는 반드시 이터레이터(iterator, 메서드 next가 있는 객체) 를 반환해야 합니다.</li>
<li>이후 for..of는 반환된 객체(이터레이터)만을 대상으로 동작합니다.</li>
<li>for..of에 다음 값이 필요하면, for..of는 이터레이터의 next()메서드를 호출합니다.</li>
<li>next()의 반환 값은 {done: Boolean, value: any}와 같은 형태이어야 합니다. done=true는 반복이 종료되었음을 의미합니다. done=false일땐 value에 다음 값이 저장됩니다.</li>
</ol>
<p>위 코드보다 조금 더 간단한 코드</p>
<pre><code>let range = {
  from: 1,
  to: 5,

  [Symbol.iterator]() {
    this.current = this.from;
    return this;
  },

  next() {
    if (this.current &lt;= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5
}</code></pre><p><strong>이터러블과 유사 배열</strong>
이터러블(iterable) 은 위에서 설명한 바와 같이 메서드 Symbol.iterator가 구현된 객체
유사 배열(array-like) 은 인덱스와 length 프로퍼티가 있어서 배열처럼 보이는 객체</p>
<p>Array.from
Array.from(obj[, mapFn, thisArg])
이터러블이나 유사 배열을 받아 ‘진짜’ Array로 만듬
mapFn을 두 번째 인수로 넘겨주면 새로운 배열에 obj의 요소를 추가하기 전에 각 요소를 대상으로 mapFn을 적용
thisArg는 각 요소의 this를 지정가능</p>
<pre><code>let arrayLike = {
  0: &quot;Hello&quot;,
  1: &quot;World&quot;,
  length: 2
};

let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (메서드가 제대로 동작합니다.)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[데코레이터]]></title>
            <link>https://velog.io/@star-ho/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0</link>
            <guid>https://velog.io/@star-ho/%EB%8D%B0%EC%BD%94%EB%A0%88%EC%9D%B4%ED%84%B0</guid>
            <pubDate>Sat, 20 Mar 2021 15:34:38 GMT</pubDate>
            <description><![CDATA[<p>** 인수로 받은 함수의 행동을 변경시켜주는 함수
** </p>
<pre><code> function slow(x) {
  // CPU 집약적인 작업이 여기에 올 수 있습니다.
  alert(`slow(${x})을/를 호출함`);
  return x;
}

function cachingDecorator(func) {
  let cache = new Map();

  return function(x) {
    if (cache.has(x)) {    // cache에 해당 키가 있으면
      return cache.get(x); // 대응하는 값을 cache에서 읽어옵니다.
    }

    let result = func(x);  // 그렇지 않은 경우엔 func를 호출하고,

    cache.set(x, result);  // 그 결과를 캐싱(저장)합니다.
    return result;
  };
}

slow = cachingDecorator(slow);

alert( slow(1) ); // slow(1)이 저장되었습니다.
alert( &quot;다시 호출: &quot; + slow(1) ); // 동일한 결과

alert( slow(2) ); // 
slow(2)가 저장되었습니다.
alert( &quot;다시 호출: &quot; + slow(2) ); // 윗줄과 동일한 결과</code></pre><p>this를 명시적으로 고정해 함수를 호출할 수 있게 해주는 특별한 내장 함수 메서드 func.call(context, …args)</p>
<p>*<em>func.call(context, arg1, arg2, ...)
*</em>메서드를 호출하면 메서드의 첫 번째 인수가 this, 이어지는 인수가 func의 인수가 된 후, func이 호출</p>
<p>데코레이터에 여러인수 전달하는 방법
두 값을 하나로 합치기. 맵의 키로 문자열 &quot;min,max&quot;를 사용합니다. 여러 값을 하나로 합치는 코드는 해싱 함수(hashing function) 에 구현해 유연성을 높입니다.</p>
<pre><code>let worker = {
  slow(min, max) {
    alert(`slow(${min},${max})을/를 호출함`);
    return min + max;
  }
};

function cachingDecorator(func, hash) {
  let cache = new Map();
  return function() {
    let key = hash(arguments); // (*)
    if (cache.has(key)) {
      return cache.get(key);
    }

    let result = func.call(this, ...arguments); // (**)

    cache.set(key, result);
    return result;
  };
}

function hash(args) {
  return args[0] + &#39;,&#39; + args[1];
}

worker.slow = cachingDecorator(worker.slow, hash);

alert( worker.slow(3, 5) ); // 제대로 동작합니다.
alert( &quot;다시 호출: &quot; + worker.slow(3, 5) ); // 동일한 결과 출력(캐시된 결과</code></pre><p>func.apply
func.apply(context, args)
apply는 func의 this를 context로 고정해주고, 유사 배열 객체인 args를 인수로 사용할 수 있게 해줌
call과 apply의 문법적 차이는 call이 복수 인수를 따로따로 받는 대신 apply는 인수를 유사 배열 객체로 받음</p>
<pre><code>func.call(context, ...args); // 전개 문법을 사용해 인수가 담긴 배열을 전달하는 것과
func.apply(context, args);   // call을 사용하는 것은 동일합니다.</code></pre><p>위 줄은 같은역할</p>
<p>차이는 아래와 같다
전개 문법 ...은 이터러블 args을 분해 해 call에 전달할 수 있도록 해줍니다.
apply는 오직 유사 배열 형태의 args만 받습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[javascript remove duplicates from a two-dimensional array
- 2차원배열 중복 제거]]></title>
            <link>https://velog.io/@star-ho/javascript-remove-duplicates-from-a-two-dimensional-array-2%EC%B0%A8%EC%9B%90%EB%B0%B0%EC%97%B4-%EC%A4%91%EB%B3%B5-%EC%A0%9C%EA%B1%B0</link>
            <guid>https://velog.io/@star-ho/javascript-remove-duplicates-from-a-two-dimensional-array-2%EC%B0%A8%EC%9B%90%EB%B0%B0%EC%97%B4-%EC%A4%91%EB%B3%B5-%EC%A0%9C%EA%B1%B0</guid>
            <pubDate>Sat, 20 Mar 2021 05:01:49 GMT</pubDate>
            <description><![CDATA[<pre><code>let Duparr=[[1,2,1],[1,2,1],[2,1,2],[3,1,4],[4,1,1]]
console.log(removeDup(Duparr))

function removeDup(arr){
    return [...new Set(arr.join(&#39;|&#39;).split(&#39;|&#39;))].map(v=&gt;v.split(&#39;,&#39;)).map(v=&gt;v.map(a=&gt;+a))
    }
//[ [ 1, 2, 1 ], [ 2, 1, 2 ], [ 3, 1, 4 ], [ 4, 1, 1 ] ]
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[연결리스트, 간선리스트, 인접행렬 변환]]></title>
            <link>https://velog.io/@star-ho/%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B0%84%EC%84%A0%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%97%B0%EA%B4%80%EB%B0%B0%EC%97%B4-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@star-ho/%EC%97%B0%EA%B2%B0%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B0%84%EC%84%A0%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%97%B0%EA%B4%80%EB%B0%B0%EC%97%B4-%EB%B3%80%ED%99%98</guid>
            <pubDate>Tue, 16 Mar 2021 11:40:59 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/star-ho/post/d43b2916-2f03-405f-9049-184670955b7d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/star-ho/post/69e6be9e-8aeb-4edf-9b9c-69a2739c6a8c/image.png" alt="">
위 그래프를 간선리스트, 연결리스트, 인접행렬로 나타내면 아래 그림과 같다</p>
<p>간선리스트를 인접행렬, 연결리스트로 바꾸는 자바스크립트는 아래와 같다</p>
<p>간선리스트에서 연결리스트</p>
<pre><code>function lineToList(node_num,line){
    let list=Array.from({length:(+node_num+1)},()=&gt;[])
    line.forEach(v=&gt;{
        list[v[0]].push(v[1]);
        list[v[1]].push(v[0]);
    })
    return list;
}
</code></pre><p>간선리스트에서 인접행렬</p>
<pre><code>function lineToGraph(node_num,line){
    let Graph=Array.from({length:(+node_num+1)},()=&gt;Array.from({length:(+node_num+1)},()=&gt;0))
    line.forEach(v=&gt;{
        Graph[v[0]][v[1]]=1
        Graph[v[1]][v[0]]=1
    })
    return Graph;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[함수 심화개념]]></title>
            <link>https://velog.io/@star-ho/%ED%95%A8%EC%88%98-%EC%8B%AC%ED%99%94%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@star-ho/%ED%95%A8%EC%88%98-%EC%8B%AC%ED%99%94%EA%B0%9C%EB%85%90</guid>
            <pubDate>Sat, 13 Mar 2021 09:52:27 GMT</pubDate>
            <description><![CDATA[<p>‘name’ 프로퍼티</p>
<pre><code>function sayHi() {
  alert(&quot;Hi&quot;);
}

alert(sayHi.name); // sayHi
------------------------------------------------------
let sayHi = function() {
  alert(&quot;Hi&quot;);
};

alert(sayHi.name); // sayHi (익명 함수이지만 이름이 있네요!)</code></pre><p>‘length’ 프로퍼티
내장 프로퍼티 length는 함수 매개변수의 개수를 반환</p>
<pre><code>function f1(a) {}
function f2(a, b) {}
function many(a, b, ...more) {}

alert(f1.length); // 1
alert(f2.length); // 2
alert(many.length); // 2</code></pre><p>클로저를 함수 프로퍼티로 사용가능</p>
<pre><code>function makeCounter() {

  function counter() {
    return counter.count++;
  };

  counter.count = 0;

  return counter;
}

let counter = makeCounter();

counter.count = 10;
alert( counter() ); // 10</code></pre><p>&#39;new Function&#39; 문법
문자열을 함수로 바꿀 수 잇음
let func = new Function ([arg1, arg2, ...argN], functionBody);</p>
<pre><code>let sum = new Function(&#39;a&#39;, &#39;b&#39;, &#39;return a + b&#39;);

alert( sum(1, 2) ); // 3</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[나머지 매개변수 ...]]></title>
            <link>https://velog.io/@star-ho/%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-</link>
            <guid>https://velog.io/@star-ho/%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-</guid>
            <pubDate>Sat, 13 Mar 2021 09:51:50 GMT</pubDate>
            <description><![CDATA[<p>함수의 정의와 상관없이 넘겨주는 인수의 개수에는 제약이 없음</p>
<pre><code>function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );//오류 발생하지않음</code></pre><p><strong>...args 배열</strong></p>
<pre><code>function sumAll(...args) { // args는 배열의 이름입니다.
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6

-------------------------------------------------------

function showName(firstName, lastName, ...titles) {
  alert( firstName + &#39; &#39; + lastName ); // Julius Caesar

  // 나머지 인수들은 배열 titles의 요소가 됩니다.
  // titles = [&quot;Consul&quot;, &quot;Imperator&quot;]
  alert( titles[0] ); // Consul
  alert( titles[1] ); // Imperator
  alert( titles.length ); // 2
}

showName(&quot;Julius&quot;, &quot;Caesar&quot;, &quot;Consul&quot;, &quot;Imperator&quot;);</code></pre><p><strong>‘arguments’ 변수</strong>
<strong><em>배열이 아닌</em></strong> 유사배열객체
인덱스를 사용해 모든 인수 접근가능</p>
<pre><code>function showName() {
  alert( arguments.length );
  alert( arguments[0] );
  alert( arguments[1] );

  // arguments는 이터러블 객체이기 때문에
  // for(let arg of arguments) alert(arg); 를 사용해 인수를 나열할 수 있습니다.
}

// 2, Julius, Caesar가 출력됨
showName(&quot;Julius&quot;, &quot;Caesar&quot;);

// 1, Bora, undefined가 출력됨(두 번째 인수는 없음)
showName(&quot;Bora&quot;);</code></pre><p>화살표 함수에는 존재하지 않음
화살표 함수에서 사용시 일반함수의 arguments객체를 가져옴</p>
<pre><code>function f() {
  let showArg = () =&gt; alert(arguments[0]);
  showArg();
}

f(1); // 1</code></pre><p><strong>spread 문법</strong>
배열을 통째로 매개변수에 넘겨주는 방법
함수를 호출할 때 ... arr를 사용하면, 이터러블 객체 arr이 인수 목록으로 확장됨</p>
<pre><code>let arr = [3, 5, 1];

alert( Math.max(...arr) ); // 5 (전개 문법이 배열을 인수 목록으로 바꿔주었습니다.)</code></pre><p>배열 복사시에도 사용가능</p>
<pre><code>let arr = [1, 2, 3];
let arrCopy = [...arr]; // spread the array into a list of parameters
                        // then put the result into a new array

// do the arrays have the same contents?
alert(JSON.stringify(arr) === JSON.stringify(arrCopy)); // true

// are the arrays equal?
alert(arr === arrCopy); // false (not same reference)

// modifying our initial array does not modify the copy:
arr.push(4);
alert(arr); // 1, 2, 3, 4
alert(arrCopy); // 1, 2, 3</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[JSON]]></title>
            <link>https://velog.io/@star-ho/JSON</link>
            <guid>https://velog.io/@star-ho/JSON</guid>
            <pubDate>Sat, 13 Mar 2021 09:51:14 GMT</pubDate>
            <description><![CDATA[<p>JSON.stringify – 객체를 JSON으로 바꿔줍니다.
JSON.parse – JSON을 객체로 바꿔줍니다.</p>
<p>JSON.stringify(value[, replacer, space])</p>
<p>value
인코딩 하려는 값
replacer
JSON으로 인코딩 하길 원하는 프로퍼티가 담긴 배열. 또는 매핑 함수 function(key, value)
space
서식 변경 목적으로 사용할 공백 문자 수</p>
<p>replacer예제</p>
<pre><code>let room = {
  number: 23
};

let meetup = {
  title: &quot;Conference&quot;,
  participants: [{name: &quot;John&quot;}, {name: &quot;Alice&quot;}],
  place: room // meetup은 room을 참조합니다.
};

room.occupiedBy = meetup; // room references meetup

alert( JSON.stringify(meetup, [&#39;title&#39;, &#39;participants&#39;]) );
// {&quot;title&quot;:&quot;Conference&quot;,&quot;participants&quot;:[{},{}]}</code></pre><p>space예제</p>
<pre><code>alert(JSON.stringify(user, null, 2));
/* 공백 문자 두 개를 사용하여 들여쓰기함:
{
  &quot;name&quot;: &quot;John&quot;,
  &quot;age&quot;: 25,
  &quot;roles&quot;: {
    &quot;isAdmin&quot;: false,
    &quot;isEditor&quot;: true
  }
}
*/</code></pre><p>JSON.parse(str, [reviver]);
str
JSON 형식의 문자열
reviver
모든 (key, value) 쌍을 대상으로 호출되는 function(key,value) 형태의 함수로 값을 변경시킬 수 있습니다.</p>
<pre><code>let userData = &#39;{ &quot;name&quot;: &quot;John&quot;, &quot;age&quot;: 35, &quot;isAdmin&quot;: false, &quot;friends&quot;: [0,1,2,3] }&#39;;

let user = JSON.parse(userData);

alert( user.friends[1] ); // 1</code></pre><p>reviver 예제</p>
<pre><code>let str = &#39;{&quot;title&quot;:&quot;Conference&quot;,&quot;date&quot;:&quot;2017-11-30T12:00:00.000Z&quot;}&#39;;

let meetup = JSON.parse(str, function(key, value) {
  if (key == &#39;date&#39;) return new Date(value);//(*)
  return value;
});

alert( meetup.date.getDate() ); // 이제 제대로 동작하네요!</code></pre><p>(*)가 reviver 예제</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Object.keys, values, entries, 구조 분해 할당]]></title>
            <link>https://velog.io/@star-ho/Object.keys-values-entries-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9</link>
            <guid>https://velog.io/@star-ho/Object.keys-values-entries-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9</guid>
            <pubDate>Sat, 13 Mar 2021 09:50:12 GMT</pubDate>
            <description><![CDATA[<p>Object.keys(obj) – 객체의 키만 담은 배열을 반환합니다.
Object.values(obj) – 객체의 값만 담은 배열을 반환합니다.
Object.entries(obj) – [키, 값] 쌍을 담은 배열을 반환합니다.</p>
<p>구조 분해 할당</p>
<pre><code>// 이름과 성을 요소로 가진 배열
let arr = [&quot;Bora&quot;, &quot;Lee&quot;]

// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당하였습니다.
let [firstName, surname] = arr;

alert(firstName); // Bora
alert(surname);  // Lee</code></pre><p>쉼표를 사용하여 요소 무시</p>
<pre><code>// 두 번째 요소는 필요하지 않음
let [firstName, , title] = [&quot;Julius&quot;, &quot;Caesar&quot;, &quot;Consul&quot;, &quot;of the Roman Republic&quot;];

alert( title ); // Consul</code></pre><p>할당 연산자 우측엔 모든 이터러블 사용가능</p>
<pre><code>let [a, b, c] = &quot;abc&quot;; // [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]
let [one, two, three] = new Set([1, 2, 3]);</code></pre><p>할당 연산자 좌측엔 뭐든지</p>
<pre><code>let user = {};
[user.name, user.surname] = &quot;Bora Lee&quot;.split(&#39; &#39;);

alert(user.name); // Bora</code></pre><p>.entries()</p>
<pre><code>let user = {
  name: &quot;John&quot;,
  age: 30
};

// 객체의 키와 값 순회하기
for (let [key, value] of Object.entries(user)) {
  alert(`${key}:${value}`); // name:John, age:30이 차례대로 출력
}</code></pre><p>&#39;…&#39;로 나머지 요소</p>
<pre><code>let [name1, name2, ...rest] = [&quot;Julius&quot;, &quot;Caesar&quot;, &quot;Consul&quot;, &quot;of the Roman Republic&quot;];

alert(name1); // Julius
alert(name2); // Caesar

// `rest`는 배열입니다.
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2</code></pre><p>기본값</p>
<pre><code>let [firstName, surname] = [];

alert(firstName); // undefined
alert(surname); // undefined

// 기본값
let [name = &quot;Guest&quot;, surname = &quot;Anonymous&quot;] = [&quot;Julius&quot;];

alert(name);    // Julius (배열에서 받아온 값)
alert(surname); // Anonymous (기본값)</code></pre><p>객체에도 사용 가능</p>
<pre><code>let options = {
  title: &quot;Menu&quot;,
  width: 100,
  height: 200
};

// { 객체 프로퍼티: 목표 변수 }
let {width: w, height: h, title} = options;

// width -&gt; w
// height -&gt; h
// title -&gt; title

alert(title);  // Menu
alert(w);      // 100
alert(h);      // 200</code></pre><p>원하는 변수만</p>
<pre><code>let options = {
  title: &quot;Menu&quot;,
  width: 100,
  height: 200
};

// title만 변수로 뽑아내기
let { title } = options;

alert(title); // Menu</code></pre><p>중첩 구조 분해</p>
<pre><code>let options = {
  size: {
    width: 100,
    height: 200
  },
  items: [&quot;Cake&quot;, &quot;Donut&quot;],
  extra: true
};

// 코드를 여러 줄에 걸쳐 작성해 의도하는 바를 명확히 드러냄
let {
  size: { // size는 여기,
    width,
    height
  },
  items: [item1, item2], // items는 여기에 할당함
  title = &quot;Menu&quot; // 분해하려는 객체에 title 프로퍼티가 없으므로 기본값을 사용함
} = options;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
alert(item1);  // Cake
alert(item2);  // Donut</code></pre><p>똑똑한 함수 매개변수</p>
<pre><code>// 함수에 전달할 객체
let options = {
  title: &quot;My menu&quot;,
  items: [&quot;Item1&quot;, &quot;Item2&quot;]
};

// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function showMenu({title = &quot;Untitled&quot;, width = 200, height = 100, items = []}) {
  // title, items – 객체 options에서 가져옴
  // width, height – 기본값
  alert( `${title} ${width} ${height}` ); // My Menu 200 100
  alert( items ); // Item1, Item2
}

showMenu(options);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[맵과 셋]]></title>
            <link>https://velog.io/@star-ho/%EB%A7%B5%EA%B3%BC-%EC%85%8B-refblpz2</link>
            <guid>https://velog.io/@star-ho/%EB%A7%B5%EA%B3%BC-%EC%85%8B-refblpz2</guid>
            <pubDate>Sat, 13 Mar 2021 09:49:18 GMT</pubDate>
            <description><![CDATA[<p><strong>맵</strong>
맵(Map)은 키가 있는 데이터를 저장한다는 점
다양한 자료형을 허용
new 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.size – 요소의 개수를 반환합니다.</p>
<p><strong>맵의 메서드</strong>
map.keys() – 각 요소의 키를 모은 반복 가능한(iterable, 이터러블) 객체를 반환합니다.
map.values() – 각 요소의 값을 모은 이터러블 객체를 반환합니다.
map.entries() – 요소의 [키, 값]을 한 쌍으로 하는 이터러블 객체를 반환합니다. 이 이터러블 객체는 for..of반복문의 기초로 쓰입니다.</p>
<p><strong>Object.entries</strong>
객체를 맵으로 변경</p>
<pre><code>let obj = {
  name: &quot;John&quot;,
  age: 30
};

let map = new Map(Object.entries(obj));

alert( map.get(&#39;name&#39;) ); // John</code></pre><p><strong>Object.fromEntries</strong>
맵을 객체로 변경</p>
<pre><code>let prices = Object.fromEntries([
  [&#39;banana&#39;, 1],
  [&#39;orange&#39;, 2],
  [&#39;meat&#39;, 4]
]);

// now prices = { banana: 1, orange: 2, meat: 4 }

alert(prices.orange); // 2</code></pre><p><strong>셋</strong>
new Set(iterable) – 셋을 만듭니다. 이터러블 객체를 전달받으면(대개 배열을 전달받음) 그 안의 값을 복사해 셋에 넣어줍니다.
set.add(value) – 값을 추가하고 셋 자신을 반환합니다.
set.delete(value) – 값을 제거합니다. 호출 시점에 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환합니다.
set.has(value) – 셋 내에 값이 존재하면 true, 아니면 false를 반환합니다.
set.clear() – 셋을 비웁니다.
set.size – 셋에 몇 개의 값이 있는지 세줍니다.</p>
<pre><code>let set = new Set();

let john = { name: &quot;John&quot; };
let pete = { name: &quot;Pete&quot; };
let mary = { name: &quot;Mary&quot; };

// 어떤 고객(john, mary)은 여러 번 방문할 수 있습니다.
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);

// 셋에는 유일무이한 값만 저장됩니다.
alert( set.size ); // 3

for (let user of set) {
  alert(user.name); // // John, Pete, Mary 순으로 출력됩니다.
}</code></pre><p>++
<strong>for..of나 forEach를 사용하여 반복작업 가능</strong></p>
<p><strong>위크맵</strong>
키가 반드시 객체
사용된 객체를 참조하는 것이 아무것도 없다면 해당 객체는 메모리와 위크맵에서 자동으로 삭제</p>
<pre><code>let john = { name: &quot;John&quot; };

let weakMap = new WeakMap();
weakMap.set(john, &quot;...&quot;);

john = null; // 참조를 덮어씀

// john을 나타내는 객체는 이제 메모리에서 지워집니다!</code></pre><p>weakMap.get(key)
weakMap.set(key, value)
weakMap.delete(key)
weakMap.has(key)
그냥 맵과는 다르게 위 4개의 메소드만 지원</p>
<p><strong>위크셋</strong>
위크셋은 셋과 유사한데, 객체만 저장할 수 있다는 점이 다릅니다. 원시값은 저장할 수 없습니다.
셋 안의 객체는 도달 가능할 때만 메모리에서 유지됩니다.
셋과 마찬가지로 위크셋이 지원하는 메서드는 단출합니다. add, has, delete를 사용할 수 있고, size, keys()나 반복 작업 관련 메서드는 사용할 수 없습니다.</p>
<pre><code>let visitedSet = new WeakSet();

let john = { name: &quot;John&quot; };
let pete = { name: &quot;Pete&quot; };
let mary = { name: &quot;Mary&quot; };

visitedSet.add(john); // John이 사이트를 방문합니다.
visitedSet.add(pete); // 이어서 Pete가 사이트를 방문합니다.
visitedSet.add(john); // 이어서 John이 다시 사이트를 방문합니다.

// visitedSet엔 두 명의 사용자가 저장될 겁니다.

// John의 방문 여부를 확인해보겠습니다.
alert(visitedSet.has(john)); // true

// Mary의 방문 여부를 확인해보겠습니다.
alert(visitedSet.has(mary)); // false

john = null;

// visitedSet에서 john을 나타내는 객체가 자동으로 삭제됩니다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[iterable 객체]]></title>
            <link>https://velog.io/@star-ho/iterable-%EA%B0%9D%EC%B2%B4-7hyqlece</link>
            <guid>https://velog.io/@star-ho/iterable-%EA%B0%9D%EC%B2%B4-7hyqlece</guid>
            <pubDate>Sat, 13 Mar 2021 09:47:49 GMT</pubDate>
            <description><![CDATA[<p><strong>배열을 일반화한 객체</strong>
iterable 객체는 for..of 반복문 적용 가능</p>
<p>Symbol.iterator
Symbol.iterator객체가 존재한다면 for..of적용 가능</p>
<pre><code>let range = {
  from: 1,
  to: 5
};

// 1. for..of 최초 호출 시, Symbol.iterator가 호출됩니다.
range[Symbol.iterator] = function() {

  // Symbol.iterator는 이터레이터 객체를 반환합니다.
  // 2. 이후 for..of는 반환된 이터레이터 객체만을 대상으로 동작하는데, 이때 다음 값도 정해집니다.
  return {
    current: this.from,
    last: this.to,

    // 3. for..of 반복문에 의해 반복마다 next()가 호출됩니다.
    next() {
      // 4. next()는 값을 객체 {done:.., value :...}형태로 반환해야 합니다.
      if (this.current &lt;= this.last) {
        return { done: false, value: this.current++ };
      } else {
        return { done: true };
      }
    }
  };
};

// 이제 의도한 대로 동작합니다!
for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5</code></pre><p><strong>range객체를 for..of호출 시 발생하는 일</strong></p>
<ol>
<li>for..of가 시작되자마자 for..of는 Symbol.iterator를 호출합니다(Symbol.iterator가 없으면 에러가 발생합니다). Symbol.iterator는 반드시 이터레이터(iterator, 메서드 next가 있는 객체) 를 반환해야 합니다.</li>
<li>이후 for..of는 반환된 객체(이터레이터)만을 대상으로 동작합니다.</li>
<li>for..of에 다음 값이 필요하면, for..of는 이터레이터의 next()메서드를 호출합니다.</li>
<li>next()의 반환 값은 {done: Boolean, value: any}와 같은 형태이어야 합니다. done=true는 반복이 종료되었음을 의미합니다. done=false일땐 value에 다음 값이 저장됩니다.</li>
</ol>
<p>위 코드보다 조금 더 간단한 코드</p>
<pre><code>let range = {
  from: 1,
  to: 5,

  [Symbol.iterator]() {
    this.current = this.from;
    return this;
  },

  next() {
    if (this.current &lt;= this.to) {
      return { done: false, value: this.current++ };
    } else {
      return { done: true };
    }
  }
};

for (let num of range) {
  alert(num); // 1, then 2, 3, 4, 5
}</code></pre><p><strong>이터러블과 유사 배열</strong>
이터러블(iterable) 은 위에서 설명한 바와 같이 메서드 Symbol.iterator가 구현된 객체
유사 배열(array-like) 은 인덱스와 length 프로퍼티가 있어서 배열처럼 보이는 객체</p>
<p><strong>Array.from</strong>
Array.from(obj[, mapFn, thisArg])
이터러블이나 유사 배열을 받아 ‘진짜’ Array로 만듬
mapFn을 두 번째 인수로 넘겨주면 새로운 배열에 obj의 요소를 추가하기 전에 각 요소를 대상으로 mapFn을 적용
thisArg는 각 요소의 this를 지정가능</p>
<pre><code>let arrayLike = {
  0: &quot;Hello&quot;,
  1: &quot;World&quot;,
  length: 2
};

let arr = Array.from(arrayLike); // (*)
alert(arr.pop()); // World (메서드가 제대로 동작합니다.)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 위장]]></title>
            <link>https://velog.io/@star-ho/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9C%84%EC%9E%A5</link>
            <guid>https://velog.io/@star-ho/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9C%84%EC%9E%A5</guid>
            <pubDate>Sat, 13 Mar 2021 02:49:47 GMT</pubDate>
            <description><![CDATA[<p><strong>문제 설명</strong>
스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.</p>
<p>예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.</p>
<p>종류    이름
얼굴    동그란 안경, 검정 선글라스
상의    파란색 티셔츠
하의    청바지
겉옷    긴 코트
스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.</p>
<p><strong>제한사항</strong>
clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
같은 이름을 가진 의상은 존재하지 않습니다.
clothes의 모든 원소는 문자열로 이루어져 있습니다.
모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 &#39;_&#39; 로만 이루어져 있습니다.
스파이는 하루에 최소 한 개의 의상은 입습니다.</p>
<p>후기 및 풀이
푸는건 얼마 안걸렸지만 다른사람 풀이를 봤는데 코드도 짧고 시간차이가 많이 나서 쪼금 아쉬웠다. 
내코드 분석보다는 잘짠 코드를 보고 정리하려 한다</p>
<pre><code>잘짠 코드
function solution(clothes) {
    return Object.values(clothes.reduce((obj, t)=&gt; {
        obj[t[1]] = obj[t[1]] ? obj[t[1]] + 1 : 1;
        return obj;
    } , {})).reduce((a,b)=&gt; a*(b+1), 1)-1;    
}</code></pre><p>reduce로 값을 반환하는 것이 아니라 객체를 반환한다.
obj[t]값이 존재하면 1을 더해서 반환하고 존재하지 않는다면 프로퍼티를 만들어 초기화해준다(이게 메인 아이디어)
이후 만든 객체에서 값만 뽑아서 1더한후(하나만 입은 경우) 곱하고 1빼기(아무것도 입지 않은 경우)</p>
<pre><code>//내풀이
function solution(clothes) {
    var answer = 0;
    let cat={};
    let arr=[];
    clothes.forEach(function(a){
        if((a[1] in cat)==0){
            cat[a[1]]=[a[0]];
            return;
        }
        cat[a[1]]=cat[a[1]].concat([a[0]]);
    })

    for(let a in cat){
        arr.push(cat[a].length)
    }
    console.log(arr)
    answer=arr.reduce((a,b)=&gt;(a*=(b+1)),1)-1
    return answer;
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[조합 순열 알고리즘 정리]]></title>
            <link>https://velog.io/@star-ho/%EC%A1%B0%ED%95%A9-%EC%88%9C%EC%97%B4-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@star-ho/%EC%A1%B0%ED%95%A9-%EC%88%9C%EC%97%B4-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 13 Mar 2021 02:26:49 GMT</pubDate>
            <description><![CDATA[<p>중복조합</p>
<ol>
<li>배열에서 하나 선택후 인덱스를 1감소시킨후 다시호출</li>
<li>인덱스가 1일경우 각 요소를 배열로 만들어 리턴</li>
<li>리턴된 값을 1에서 선택한 값과 합침</li>
</ol>
<p>중복조합</p>
<pre><code>function perm(array, length) {
    return array.flatMap((v, i) =&gt; length &gt; 1
        ? perm(array, length - 1).map(w =&gt; [v, ...w])
        : [[v]]
    );
}
perm([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;], 3).forEach(a =&gt; console.log(...a));
</code></pre><p>조합</p>
<ol>
<li>배열에서 하나 선택후 선택한 요소를 제외한 배열과 인덱스를 1감소시킨후 다시호출</li>
<li>인덱스가 1일경우 각 요소를 배열로 만들어 리턴</li>
<li>리턴된 값을 1에서 선택한 값과 합침</li>
</ol>
<p>조합 코드</p>
<pre><code>function comb(array, length) {
    return array.flatMap((v, i) =&gt; length &gt; 1
        ? comb(array.slice(i + 1), length - 1).map(w =&gt; [v, ...w])
        : [[v]]
    );
}
comb([&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;], 3).forEach(a =&gt; console.log(...a));</code></pre><p>순열</p>
<pre><code>const perm= function (arr, len) {
    const results = [];
    if (len === 1) return arr.map((value) =&gt; [value]); // 1개씩 택할 때, 바로 모든 배열의 원소 return

    arr.forEach((fixed, index, origin) =&gt; {
      const rest = [...origin.slice(0, index), ...origin.slice(index+1)] // 해당하는 fixed를 제외한 나머지 배열 
      const permutations = perm(rest, len - 1); // 나머지에 대해 순열을 구한다.
      const attached = permutations.map((permutation) =&gt; [fixed, ...permutation]); // 돌아온 순열에 대해 떼 놓은(fixed) 값 붙이기
      results.push(...attached); // 배열 spread syntax 로 모두다 push
    });

    return results; // 결과 담긴 results return
};</code></pre><p><a href="https://www.python2.net/questions-777952.htm">https://www.python2.net/questions-777952.htm</a>
<a href="https://jun-choi-4928.medium.com/javascript%EB%A1%9C-%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-21df4b536349">https://jun-choi-4928.medium.com/javascript%EB%A1%9C-%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-21df4b536349</a></p>
]]></description>
        </item>
    </channel>
</rss>