반응형

map() 메서드

map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다.

 

구문

arr.map(callback(currentValue[, index[, array]])[, thisArg])

 

매개변수

  • callback: 새로운 배열 요소를 생성하는 함수( 아래 세 가지 인수를 가집니다. )
  • currentValue: 처리할 현재 요소
  • index: 처리할 현재 요소의 인덱스
  • array: map()을 호출한 배열
  • thisArg: callback을 실행할 때 this로 사용되는 값

 

반환 값

배열의 각 요소에 대해 실행한 callback의 결과를 모은 새로운 배열

 

예제

배열에 들어있는  숫자들의 제곱근을 구하여 새로운 배열을 만들기

let number = [1, 4, 9, 21];
let roots = number.map(Math.sqrt);

console.log(number); // [1, 4, 9, 21]
console.log(roots); // [1, 2, 3, 4.58257569495584]

 

map()을 활용해 배열 속 객체를 재구성하기

let kvArr = [
  { key: 1, value: 10 },
  { key: 2, value: 20 },
  { key: 3, value: 30 }
];

let reformttedArr = kvArr.map(function (obj) {
  let rObj = {};
  rObj[obj.key] = obj.value;

  return rObj;
});

console.log(kvArr); // [{key:1, value: 10}, {key:2, value: 20}, {key:3, value: 30}]
console.log(reformttedArr); // [{1: 10}, {2: 20}, {3: 30}]

 

인자를 받는 함수를 사용하여 숫자 배열 재구성하기

let number = [1, 2, 5, 8, 20];

let double = number.map(function (num) {
  return num * 2;
});

console.log(number); // [1, 2, 5, 8, 20]
console.log(double); // [2, 4, 10, 16, 40]

 

map()을 포괄적으로 사용하기

:: ASCII 인코딩 값을 요소로 갖는 배열을 얻는 방법입니다.

let map = Array.prototype.map;

let a = map.call("Hello World", function (x) {
  return x.charCodeAt(0);
});

console.log(a); // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

 

반응형
반응형

최근 reduce()를 사용하는 일이 나오기 시작했는데 제대로 사용을 못하는 문제로 인하여 작성하게 된 글입니다.

javascript에서 reduce()는 반복 프로세스를 통해서 배열을 단일 값으로 축소하는 데 사용됩니다.

누적기와 함께 배열의 각 요소에 제공된 콜백 함수를 적용하고 단일 누적 결과를 반환해줍니다.

 

구문

array.reduce(callback, initialValue);
  • array: 축소 시키려는 배열입니다.
  • callback: 배열의 각 요소에 대해 호출되는 함수로 4개의 인수를 사용합니다.
    - accumulator: 이전 반복의 누적된 결과입니다.
    - currentValue: 현재 처리 중인 요소입니다.
    - currentInext: (선택사항) 처리 중인 요소의 현재 인덱스입니다.
    - array: (선택사항) 호출된 배열입니다. reduce
  • initialValue: (선택사항) 누산기의 초기 값입니다. 제공되지 않으면 배열의 첫 번째 요소가 초기 누산기 값으로 사용되고 두 번째 요소부터 반복이 시작됩니다.

 

작동방식

1. initialValue 초기 값이 들어옵니다 ( 없으면 배열의 첫 번째 요소가 초기 값이 됩니다. )

2. initialValue 콜백 함수는 두 번째 요소( 또는 제공되지 않았을 경우 첫 번째 요소 )부터 시작해서 각 요소에 대해 호출됩니다.

3. 각 반복에서 콜백 함수는 현재 accumulator값, currentValue 처리중인 요소의 선택적으로 currentIndex및 array 자체를 받습니다.

4. accumulator콜백 함수는 다음 반복에서 새로운 값이 될 값을 반환해야 합니다.

5. reduce() 메서드는 계속해서 배열을 반복하면서 각 요소에 콜백 함수를 적용하고 그에 따라 누산기를 업데이트 합니다.

6. 모든 요소가 처리되면 최종 누산기 값이 작업 결과로 반환됩니다.

 

.js ( 더하기 )

const num = [1, 2, 3, 4, 5];

const sum = num.reduce((accumulator, currentValue) => {
    return accumulator + currentValue;
}, 0);

console.log(sum); // 15

 

.js ( 곱하기 )

const num = [1, 2, 3, 4, 5];

const product = num.reduce((acc, current) => {
    return acc * current
}, 1);

console.log(product); // 120

 

.js ( 배열 합치기 )

const arr = [[1, 2], [3, 4], [5, 6]];

const newArr = arr.reduce((acc, current) => {
    return acc.concat(current);
}, []);

console.log(newArr); // [1, 2, 3, 4, 5, 6]

 

.js ( 중복 횟수 )

const fruits = ["apple", "banana", "apple", "orange", "banana", "apple"];

const fruitCount = fruits.reduce((acc, current) => {
    acc[current] = (acc[current] || 0) + 1;

    return acc;
}, {});

console.log(fruitCount); // { apple: 3, banana: 2, orange: 1 }

 

.js ( 그룹화 )

const students = [
    { name: "Alice", grade: "A" },
    { name: "Jun", grade: "B" },
    { name: "shiro", grade: "A" }
];

const groupByGrade = students.reduce((acc, student) => {
    const grade = student.grade;
    acc[grade] = (acc[grade] || []).concat(student);

    return acc;
}, {});

console.log(groupByGrade);
/*
{
    A: [ { name: "Alice", grade: "A" }, { name: "Shiro", grade: "A" } ],
    B: [ { name: "Jun", grade: "B" } ]
}
*/

 

.js ( 최대값 찾기 )

const num = [10, 5, 8, 20, 15];

const max = num.reduce((acc, current) => {
    return Math.max(acc, current);
}, -Infinity);

console.log(max); // 20

 

.js ( 문자열 결합하기 )

위와 아래 차이는 첫번째 글자에 공백이 들어가냐 안들어가냐 차이입니다.

const words = ["Hello", "World", "!!!"];

const sentence = words.reduce((acc, current) => {
    return acc + " " + current;
}, "");

console.log(sentence); //  Hello World !!!


//----------//

const words = ["Hello", "World", "!!!"];

const sentence = words.reduce((acc, current) => {
    return acc + " " + current;
});

console.log(sentence); // Hello World !!!

 

.js ( 초기 값을 사용한 데이터 변환 )

const data = [1, 2, 3, 4, 5];

const result = data.reduce((acc, current) => {
    acc[current] = current * 2;

    return acc;
}, {})

console.log(result); // { 1: 2, 2: 4, 3: 6, 4: 8, 5: 10 }

 

reduce() 메서드를 사용하면 위처럼 다양한 활용이 가능합니다.

그러나 한편으로는 배열 크기와 제공하는 콜백 함수의 복잡성에 따라 잘 생각하고 사용해야 합니다.

 

1. 배열 크기: 매우 큰 배열에 적용할 경우 reduce()메서드의 반복 특성으로 인해 성능 문제가 발생할 수 있으며, 콜백 함수의 계산 비용이 많이 드는 경우 더욱 그렇습니다.

2. 콜백 함수: 콜백 함수의 복잡성은 성능에 영향을 미칠 수 있습니다. 콜백 함수가 비용이 많이 드는 작업을 수행하거나 시간 복잡도가 높은 경우 코드 속도가 느려질 수 있습니다.

3. 가독성 및 유지 관리 용이성: reduce()메서드는 많은 작업을 위한 강력한 도구지만 코드 가독성과 유지 관리용이성을 우선시하는 것이 중요합니다. 정말 간단한 작업에 사용한다면 코드가 덜 명확해 질 수 있습니다.

 

반응형
반응형

버튼을 클릭했을 때 현재 url 주소를 복사하는 방법입니다.

 

.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <button onclick="copyCurrentURL()">클릭</button>

        <script>
            function copyCurrentURL() {
                // URL 가져오기
                const currentURL = window.location.href;

                // 요소 생성하기 | 꾸미기 | currentURL주소 추가하기
                const input = document.createElement("input");
                input.style.position = "fixed";
                input.style.opacity = "0";
                input.value = currentURL;

                // 문서에 입력요소 추가하기
                document.body.appendChild(input);

                // URL 텍스트 선택하기 || setSelectionRange: 모바일인 경우
                input.select();
                input.setSelectionRange(0, 99999);

                // URL 클립보드에 복사하기
                document.execCommand("copy");

                // 임시 입력 요소 제거하기
                document.body.removeChild(input);

                alert("복사완료" + currentURL);
            }
        </script>
    </body>
</html>

 

위 내용을 사용하다가 아래와같은 경고내용이 등장한 때가 있었습니다.

Signature '(commandId: string, showUI?: boolean | undefined, value?: string | undefined): boolean' is deprecated.

document.execCommand("copy")방법이 실제로 더 이상 사용되지 않다는 내용인 것 같습니다. ( 그냥 HTML에서는 그대로 사용이 가능한 것 같습니다. )

그래서 아래와 같은 방법으로 변경해서 사용을 했습니다.

 

.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <button onclick="copyCurrentURL()">클릭</button>

        <script>
            function copyCurrentURL() {
                const currentURL = window.location.href;

                navigator.clipboard.writeText(currentURL)
                .then(() => {
                    alert('Current URL copied to clipboard: ' + currentURL);
                })
                .catch(err => console.error('Copy Failed:', err));
            }
        </script>
    </body>
</html>

navigator.clipboard.writeText 메서드를 사용해서 현재 URL을 클립보드에 추가합니다.

writeText메서드는 약속을 반환하기 때문에 .then()과 .catch()를 사용하여 성공 및 실패를 처리합니다.

위와같이 사용하면 최신 웹 애플리케이션에서 정상적으로 사용할 수 있습니다. ( 저는 next.js를 사용할 때 빗금이 그려져서 위 방법으로 바꾸었습니다. )

반응형
반응형

Javascript를 사용한 간단한 전자 서명입니다.

:: 인증, 암호화, 디지털 인증서와 같은 보안 측면은 포함되지 않습니다.

 

See the Pen Untitled by JunHyeok Noh (@JunHyeok-Noh) on CodePen.

위 전자 서명 내용은 마우스를 사용하여 서명을 할 수 있는 캔버스 요소를 만듭니다.

초기화를 누르면 캔버스를 지울 수 있고, 서명 저장을 누르면 그려진 서명을 이미지로 변환시켜서 띄워줍니다.

:: 위 내용은 법적으로 유효한 전자 서명에서는 사용 할 수 없기 때문에 실제로 서명을 해야할 때는 서명 플랫폼이나 라이브러리를 사용해야 합니다.

 

위 코드의 간단한 설명

 

HTML

  • <canvas></canvas>: 전자 서명을 그리기 위한 영역입니다. width: 400, height: 200으로 설정했습니다.
  • 두개의 버튼을 추가했습니다.
    초기화: 캔버스를 초기화하는 버튼입니다.
    서명 저장: 캔버스를 이미지로 변환시켜서 띄워주는 버튼입니다.

 

JAVSCRIPT

  • canvas 변수는 요소를 참조합니다.
  • context변수는 2D 그리기 컨텍스트를 가져옵니다.
  • drawing변수는 현재 캔버스에 그림을 그리고 있는지에 대한 여부를 추적하는데 사용됩니다.
  • addEventListerner는 캔버스가 마우스 동작을 감지하도록 설정되어 있습니다.
    마우스를 캔버스 위에서 누르면 drawing을 true로 설정하고 드로잉 경로를 시작해서 드로잉이 시작됩니다.  (mousedown)
    마우스를 캔버스 위에서 누른 상태로 이동할 때 drawing이 true인 경우 경로에 점을 추가하여 드로잉된 경로가 추가됩니다. (mousemove)
    마우스를 캔버스 위에서 때면 drawing을 false로 설정하고 드로잉을 종료합니다. (mouseup)
  • clearButton의 click event는 메서드를 호출하여 캔버스를 지워줍니다.
  • saveButton의 click event는 메서드를 사용하여 캔버스에 그려진 서명을 데이터 URL로 변환시켜줍니다. toDataURL() 메서드를 사용하여 캔버스에 그려진 서명 데이터 URL로 변환시켜줍니다. 결과 데이터 URL은 서명을 이미지로 표시하는 src 속성으로 설정됩니다. 이 후, style.display를 block으로 설정해서 서명 이미지를 표시해줍니다.
반응형
반응형

날짜를 계산할 때 초 단위로 바꾸고 계산하는 것이 좋습니다. 이 때, getTime()을 사용하면 간단하게 초 단위로 변환이 가능합니다.

 

1 milliseconds = 1 / 1,000 초

1 seconds = 1,000 milliseconds

1 minute = 60seconds ( 60 * 1,000 = 60,000 milliseconds )

1 hour = 60minute ( 60 * 60 * 1,000 = 3,600,000 milliseconds )

1 day = 24 hour ( 24 * 60 * 60 * 1,000 )

 

예시 )

Fri Jun 30 2023 17:51:05 GMT+0900 (대한민국 표준시)

Fri Jun 30 2023 17:52:05 GMT+0900 (대한민국 표준시)

위처럼 날짜를 계산하기 위해서는 초 단위로 변환을 시킨 후 계산하는 것이 간단합니다. 이럴 때 초 단위로 변환시켜주는 getTime() 메서드를 사용하면 간단하게 변환을 할 수 있습니다.

 

.js

const dateString = "Fri Jun 30 2023 17:50:05 GMT+0900 (대한민국 표준시)";

const date = new Date(dateString);

const milliseconds = date.getTime();

console.log(milliseconds); // 1688115005000

위처럼 Unix epoch ( 1970년 1월 1일 0:00:00 UTC )를 기점으로 삼아 밀리초를 계산해서 반환해줍니다.

 

반응형
반응형

객체배열에 키를 빼고 값만 가져와서 배열을 만드는 방법입니다.

 

.JS

const data = [
  { user: '123' },
  { user: '456' }
];

위와같은 배열 안에 있는 값인 '123'과 '456'만 빼서 배열로 만드는 방법입니다.

 

원하는 형태

['123', '456']

 

.map을 사용한 방법

const flatArray = data.map(item => item.user);

console.log(flatArray); // ['123', '456']

 

.flatMap을 사용한 방법

const flatArray = data.flatMap(item => item.user);

console.log(flatArray); // ['123', '456']

 

.reduce를 사용한 방법

const flatArray = data.reduce((acc, item) => {
    acc.push(item.user);
    return acc;
}, [] as string[]);

console.log(flatArray); // ['123', '456']

 

.forEach를 사용한 방법

const flatArray: string[] = [];

data.forEach(item => {
    flatArray.push(item.user);
});

console.log(flatArray); // ['123', '456']

 

.map + spread operator를 사용한 방법

const flatArray = [...data.map(item => item.user)];

console.log(flatArray); // ['123', '456']

 

 

반응형
반응형

moment.js를 사용하던 도중 아래와 같은 경고문이 자꾸 나와서 day.js로 변경하였습니다.

 

moment.js를 사용하던 도중 나오던 경고문

Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions.

 

moment.js가 여전히 많이들 사용하고 있지만, 업데이트가 1년전부터 완전히 멈춰있었습니다.

저도 문제없이 사용하던 중에 위와같은 경고문을 발견한 이후로 다른걸로 바꿔봐야 겠다는 생각을 했습니다.

 

그러던 중에 day.js를 발견했습니다.

내용을 읽어보니 Moment.js와 호환되는 API를 사용해서 최신 브라우저의 날짜와 시간을 구문 분석, 유효성 검사, 조작 및 표시하는 Javascript 라이브러리라고 합니다.

Moment.js와 사용법이 매우 유사하다고 생각합니다.

사용을 해봤는데 import를 해준 이후 moment부분을 dayjs로 바꿔줬을 뿐인데, 잘 작동됐습니다.

한국어 지원도 하고 있기에 day.js로 갈아타버렸습니다.

 

npm

$ npm install dayjs

 

dayjs 불러오기

import dayjs from 'dayjs';
// 한글화
import 'dayjs/locale/ko';
dayjs.locale('ko');

 

.format()을 사용해서 dayjs 불러오기

dayjs().format("YYYY년 MM월 DD일 a h:mm:ss")

 

.fromNow()를 사용해서 dayjs 불러오기

.fromNow()를 사용하기 위해서는 몇가지를 더 추가해 줘야합니다.

 

relativeTime 불러오기

import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(relativeTime);

 

.formNow() 불러오기

dayjs().fromNow()

 

moment.js와 내용은 똑같이 나오기 때문에 따로 정리해 두지는 않았습니다.

 

moment.js 확인하러 가기

 

 

반응형
반응형

moment.js를 사용하는 방법에 대한 정리입니다.

moment.js는 시간을 관리할 때 굉장히 편리한 npm입니다.

 

npm

$ npm install moment --save

 

moment 불러오기

// moment 불러오기
import moment from 'moment';
// moment를 한글로 사용할 수 있도록 도와줍니다.
import 'moment/locale/ko';

 

.format()을 사용해서 moment 불러오기

// 현재 날짜 및 시간을 불러옵니다.
moment().format(); // 2023-06-13T17:53:12+09:00

// MMMM: 6월, Do: 13일, YYYY: 2023, h: 5, mm: 55, ss: 21, a: 오후
moment().format("MMMM Do YYYY, h:mm:ss a") // 6월 13일 2023, 5:55:21 오후

// 아래처럼 여러가지 방식으로 사용할 수 있습니다.
moment().format("YYYY년 MM월 DD일 A hh:mm:ss") // 2023년 06월 13일 오후 05:56:28

// 요일만 불러오기
moment().format("dddd"); // 화요일

 

.fromNow()를 사용해서 moment 불러오기

// 현재
moment().fromNow() // 몇 초전

// startOf('hour'): 최근 시간부터 지난 분입니다.
moment().startOf('hour').fromNow() // 3분전 ( 현재 시간이 18시 03분이었습니다. )

// endOf('day'): 24시까지의 남은 시간입니다.
moment().endOf('day').fromNow() // 6시간 후 ( 24시간 기준으로 endOf이기 때문에 6시간 남았습니다. )

// startOf('day'): 00시부터 지난 시간입니다.
moment().startOf('day').fromNow() // 18시간 전

// 2012년 06월 20일부터 지난 년도입니다.
moment("20120620", "YYYYMMDD").fromNow() // 11년 전

// 2023년 06월 01일부터 지난 일입니다.
moment("20230601", "YYYYMMDD").fromNow() // 13일 전

 

.calendar()를 사용하여 moment 불러오기

// 10일전 날짜를 불러옵니다.
moment().subtract(10, 'days').calendar() // 2023.06.03. ( 현재는 06월 13일 입니다. )

// 7일전까지는 아래처럼 지난주 ?요일 오후 시간으로 표현됩니다.
moment().subtract(5, 'days').calendar() // 지난주 목요일 오후 6:21

// 현재 시간입니다.
moment().calendar() // 오늘 오후 6:23

// 내일 시간입니다.
moment().add(1, 'days').calendar() // 내일 오후 6:23

// 7일전까지는 아래처럼 표현됩니다.
moment().add(3, 'days').calendar() // 금요일 오후 6:24

// 10일뒤 날짜입니다.
moment().add(10, 'days').calendar() // 2023.06.23

 

 

반응형
반응형

나머지가 1이 되는 수 찾기

 

문제 설명
자연수 n이 매개변수로 주어집니다. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return 하도록 solution 함수를 완성해주세요. 답이 항상 존재함은 증명될 수 있습니다.

제한사항
3 ≤ n ≤ 1,000,000
입출력 예

n result
10 3
12 11


입출력 예 설명
입출력 예 #1

10을 3으로 나눈 나머지가 1이고, 3보다 작은 자연수 중에서 문제의 조건을 만족하는 수가 없으므로, 3을 return 해야 합니다.
입출력 예 #2

12를 11로 나눈 나머지가 1이고, 11보다 작은 자연수 중에서 문제의 조건을 만족하는 수가 없으므로, 11을 return 해야 합니다.

 

function solution(n) {
    var answer = 0;
    let arr = [];
    
    for (let i = 1; i <= n - 1; i++) {
        if ((n - 1) % i === 0) arr.push(i)
    }
    
    answer = (n - 1) / arr[arr.length - 2]
    
    return answer;
}

console.log(solution(10)); // 3
console.log(solution(12)); // 11

answer = (n - 1) / arra[arr.length - 2] 부분에서 한참 헤매었습니다..ㄷㄷ

 

다른 사람의 풀이

function solution(n, x = 1) {    
    while (x++) {
        if (n % x === 1) {
            return x;
        }
    }    
}

 

또 다른 사람의 풀이

function solution(n) {
    let answer = [];

    for (let i = 1; i<=n; i++) {
        if (n % i === 1) {
            answer.push(i);
        }
    }

    return Math.min(...answer);
}

제가 처음에 이렇게 하고 싶었던 것 같습니다..!

반응형
반응형

내적

 

문제 설명
길이가 같은 두 1차원 정수 배열 a, b가 매개변수로 주어집니다. a와 b의 내적을 return 하도록 solution 함수를 완성해주세요.

이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

제한사항
a, b의 길이는 1 이상 1,000 이하입니다.
a, b의 모든 수는 -1,000 이상 1,000 이하입니다.
입출력 예

a b result
[1,2,3,4]  [-3,-1,0,2] 3
[-1,0,1]  [1,0,-1]  -2


입출력 예 설명
입출력 예 #1

a와 b의 내적은 1*(-3) + 2*(-1) + 3*0 + 4*2 = 3 입니다.
입출력 예 #2

a와 b의 내적은 (-1)*1 + 0*0 + 1*(-1) = -2 입니다.

 

function solution(a, b) {
    var answer = 1234567890;
    let num = 0;
    
    for (let i = 0; i < a.length; i++) {
        num = num + (a[i] * b[i]);
    }
    
    answer = num
    return answer;
}

console.log(solution([1,2,3,4], [-3,-1,0,2])); // 3
console.log(solution([-1,0,1], [1,0,-1]	)); // -2

 

다른 사람의 풀이

function solution(a, b) {
    return a.reduce((acc, _, i) => acc += a[i] * b[i], 0);
}

reducer..!!!

 

반응형

+ Recent posts