본문 바로가기
JavaScript/JavaScript

Javascript) 구조분해할당-배열

by 박채니 2022. 5. 25.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


구조분해할당 (Destructuring Assignment)

- 비구조할당

- 배열/객체 요소를 손쉽게 변수에 옮겨담는 문법

 

 

배열 구조분해할당 - 기본

 

HTML 코드

<button onclick="test1();">기본</button>

 

Javascript 코드

 

구조분해할당을 사용하지 않을 때

const test1 = () => {
    const arr = [1, 2, 3];
    const a = arr[0];
    const b = arr[1];
    const c = arr[2];

    console.log(a, b, c);
}

 

구조분해할당을 사용하지 않고 배열의 요소를 변수에 담을 때는 위처럼 각각 인덱스를 참조하여 값을 가져와 대입하였습니다.

 

구조분해할당 사용 시

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

console.log(a, b, c);

배열의 인덱스 순서대로 arr의 0번지의 요소를 변수 a에, 1번지의 요소를 변수 b에 2번지의 요소를 변수 c에 담도록 하였습니다.

변수명은 자유롭게 지정이 가능하며, 인덱스의 순서대로 값이 대입되는 것을 확인할 수 있습니다.

 

필요없는 번지수 생략 가능

const arr = [1, 2, 3];
const [a, b] = arr;

console.log(a, b);

2번지의 요소가 필요없다면, 생략할 수도 있습니다.

 

변수 생략 시 해당 인덱스 값은 버림 (중간 인덱스 생략)

const arr = [1, 2, 3];
const [a, ,c] = arr;

console.log(a, c);

1번지의 값을 가져왔지만 해당 요소를 담을 변수가 존재하지 않으므로 버려졌습니다.

 

존재하지 않는 인덱스는 undefined 대입

const arr = [1, 2, 3];
const [a, b, c, d] = arr;

console.log(a, b, c, d);

존재하지 않는 3번지의 값을 가져와 변수 d에 대입하려고 할 때, 오류가 발생하진 않으며 해당 변수에 undefined가 대입되는 것을 확인할 수 있습니다.

(단 가져온 d에서 또다른 작업을 할 경우, 오류 발생)

 

존재하지 않는 인덱스는 기본 값 처리 가능

const arr = [1, 2, 3];
const [a, b, c, d=999] = arr;

console.log(a, b, c, d);

존재하지 않는 인덱스에 대해서 기본 값 처리가 가능합니다.

따라서 존재하지 않는 인덱스의 값을 가진 변수 d에 기본 값 999를 대입하니 999가 출력되는 것을 확인할 수 있습니다.

 

const arr = [1, 2, 3];
const [a, b, c=99, d=999] = arr;

console.log(a, b, c, d);

존재하는 인덱스는 기본 값을 지정해도 해당 값이 적용되지 않는 것을 확인할 수 있습니다.

 

나머지 파라미터 이용

const arr = [1, 2, 3];
const [a, ...brr] = arr;

console.log(arr, a, brr);

나머지 파라미터를 이용하여 이후 요소들을 brr배열에 대입하였습니다.

원본 배열 arr에 대해선 변동 되는 것이 없습니다.

 

변수 값 교환 활용

let x = 10;
let y = 20;
[x, y] = [y, x];
console.log(x, y);

[y, x] 배열의 요소 값을 차례대로 변수 x, y에 대입되어 값 교환이 일어난 것을 확인할 수 있습니다.

구조분해할당을 이용하지 않는다면 값을 담을 다른 변수를 선언하여 옮겨야겠죠.

 

let x = 10;
let y = 20;
let temp = x;
x = y;
y = temp;
console.log(x, y);

 


배열 구조분해할당 - 활용

 

HTML 코드

<button onclick="test2();">활용</button>

 

Javascript 코드

 

매개변수부 활용

const test2 = () => {
    // 매개변수부
    process1([1, 2, 3]);
};

const process1 = ([a, b, c, d=0.5]) => {
    console.log(a, b, c, d);
};

매개인자로 배열을 넘겨주고, 매개변수로 값을 받아 출력해보았습니다.

변수 d는 기본 값 처리를 하였기 때문에 0.5가 출력 되는 것을 확인할 수 있습니다.

 

const test2 = () => {
    // 매개변수부
    console.log(process1([1, 2, 3]));
    console.log(process1([10, 20, 30, 40]));
};

const process1 = ([a, b, c, d=0.5]) => {
    console.log(a, b, c, d);
    return (a * b) / c + d;
};

매개변수로 받아 값 처리 후 리턴한 결과를 출력하였습니다.

두 번째 결과 값은 d의 값이 존재하므로 40이 출력되는 것을 확인할 수 있습니다.

 

리턴 값 활용

const test2 = () => {
    // 리턴값
    const [a, b] = process2();
    console.log(a, b);
};

const process2 = () => {
    const a = Math.floor(Math.random()*100) + 1;    // 1~100
    const b = Math.floor(Math.random()*100) + 101;  // 100~200
    return [a, b];
};

process2()함수의 리턴 값이 [a, b] 배열이기 때문에 해당 값을 차례대로 받아 변수 a, b에 대입하여 출력하였습니다.

 


@실습 - 산술 연산

- 두 수를 전달 받아 합, 차, 곱, 몫, 나머지를 동시에 리턴하는 함수

 

HTML 코드

<button onclick="test3();">@실습문제 - 산술연산</button>

 

Javascript 코드

const test3 = () => {
    let [sum, subtract, multiply, divide, remainder] = calc([10, 3]);
    console.log(sum);
    console.log(subtract);
    console.log(multiply);
    console.log(divide);
    console.log(remainder);

    [sum, subtract, multiply, divide, remainder] = calc([5, 7]);

    console.log(sum);
    console.log(subtract);
    console.log(multiply);
    console.log(divide);
    console.log(remainder);
}; 

const calc = ([a, b]) => [a+b, a-b, a*b, Math.floor(a/b), a%b];

 

 

@실습문제 - 학생점수

다음과 같이 출력하는 printStudentInfo 함수를 작성하세요.

- printStudentInfo([name, gender, ...scores])

 

- 홍길동(남) 평균 80.0점

- 신사임당(여) 평균 79.3점

- 전봉준(남) 평균 70.7점

 

HTML 코드

<button onclick="test4();">@실습문제 - 학생점수</button>

 

Javascript 코드

중간점검

const test4 = () => {
    const data = "홍길동,남,90,80,70|신사임당,여,88,100,50|전봉준,남,55,80,77";

    const splitData = data.split('|');
    splitData.map((str) => str.split(',')).forEach((arr) => printStudentInfo(arr));
};

const printStudentInfo = ([name, gender, ...scores]) => {
    console.log(name, gender, scores);
};

 

const test4 = () => {
    const data = "홍길동,남,90,80,70|신사임당,여,88,100,50|전봉준,남,55,80,77";

    const splitData = data.split('|');
    splitData.map((str) => str.split(',')).forEach((arr) => printStudentInfo(arr));
};

const printStudentInfo = ([name, gender, ...scores]) => {
    let sum = scores.map((score) => Number(score)).reduce((sum, num) => sum + num);
    let avg = Math.round(sum / scores.length*10) / 10;

    if(avg.toString().indexOf('.') === -1) avg+='.0';

    console.log(`${name}(${gender}) 평균 ${avg}점`);
};

'|' 기준으로 자른 후 map()을 통해 ','도 자른 후 배열로 반환하여 forEach()로 printStudentInfo의 매개인자로 배열을 넘겨주었습니다.

순서대로 name, gender, ...scores 변수에 담아주었으며, map()을 이용해 score를 Number로 변환한 배열을 리턴 해주고 reduce()로 각각의 합을 더해주었습니다. (초기값 0을 세팅해주지 않아도 첫번째 값을 기준으로 삼기에 생략 가능)

그 후 평균을 구해주었으며 (소수점 자리 표현을 위해 *10 / 10 처리), 딱 떨어지는 80점은 .0 처리가 되지 않아 indexOf()를 통해 '.'이 없다면 (존재하지 않으면 -1 리턴) '.0'을 추가하도록 하였습니다.

indexOf()는 number타입에는 존재하지 않는 메소드이므로 toString()으로 avg를 문자화하여 처리해주었습니다.