0389

FE

[JS] JavaScript 필수 자료구조 & 메서드 정리 — 배열·문자열·객체·Set·정렬까지 한 번에

| 서론

JavaScript를 사용하다 보면 “문법은 아는데, 막상 문제를 풀거나 코드를 짜려면 손이 안 움직이는 순간”이 자주 온다.

특히 코딩테스트나 알고리즘 문제, 혹은 실무에서 데이터를 가공할 때 배열, 문자열, 객체, Set/Map, 정렬 같은 기본 자료구조와 메서드에 익숙하지 않으면 불필요하게 for문을 늘리거나, 로직이 복잡해지는 경우가 많다.

이 글은 그런 상황을 줄이기 위해 JavaScript에서 가장 자주 쓰이는 기본 자료구조와 메서드들을 언제 쓰는지, 어떤 특징이 있는지, 실전에서 바로 적용 가능한 패턴 위주로 한 번에 정리한 노트다.

1. 배열

1) 배열 생성 & 순회

(1) 배열 생성

- new Array()

JavaScript
// ( ) 안에 값을 넣으면 된다.
const arr1 = new Array(1, 2, 3);
console.log(arr1); // [1, 2, 3]
JavaScript
// ( ) 안에 숫자 1개만 넣으면 '길이'로 인식된다.
const arr2 = new Array(3);
console.log(arr2); // [ <3 empty items> ]

- Array.from

JavaScript
// 문자열을 넣으면, 문자 단위로 쪼개진다.
const arr = Array.from("hello");
console.log(arr); // ['h', 'e', 'l', 'l', 'o']
JavaScript
// 이터러블 객체로 변환도 가능하다.
const numbers = Array.from({ length: 5 }, (_, i) => i);
console.log(numbers); // [0, 1, 2, 3, 4]

(2) 배열 순회

- for : 성능 제어, break/continuer가 필요할 때 유리

JavaScript
const arr = [10, 20, 30];

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

- for ... of

JavaScript
const arr = [10, 20, 30];

for (const value of arr) {
  console.log(value);
}

- forEach : 콜백 기반 순회, break/return으로 반복 중단 불가

JavaScript
const arr = [10, 20, 30];

arr.forEach((value, index) => {
	console.log(index, value);
});

(3) 인덱스 접근

- 대괄호로 접근

JavaScript
const arr = ["apple", "banana", "cherry"];

console.log(arr[0]); // apple
console.log(arr[1]); // banana
console.log(arr[2]); // cherry

- 인덱스를 활용한 수정

JavaScript
arr[1] = "orange";
console.log(arr); // ["apple", "orange", "cherry"]

요약1. 생성 : Array.from()2. 순회- 인덱스 필요 : for- 값만 필요 : for..of- 렌더/처리 : forEach3. 접근 : arr[index]

2) 배열 메서드

(1) push, pop : stack에 적합

- push : 배열 끝에 추가

JavaScript
const arr = [1, 2];
arr.push(3);

console.log(arr) // [1, 2, 3]

- pop : 배열 끝 요소 제거

JavaScript
const arr = [1, 2, 3];
const last = arr.pop();

console.log(last); // 3
console.log(arr); // [1, 2]

(2) shift, unshift : queue에 적합

- unshift : 배열 앞에 추가

JavaScript
const arr = [2, 3];
arr.unshift(1);

console.log(arr); // [1, 2, 3]

- shift : 배열 앞 요소 제거

JavaScript
const arr = [1, 2, 3];
const first = arr.shift();

console.log(fisrt); // 1
console.log(arr); // [2, 3]

(3) slice, splice

- slice : 원본 유지, 잘라서 반환

JavaScript
// 방법1 : 특중 구간
array.slice(start, end)
// start : 시작 인덱스 (포함)
// end : 끝 인덱스 (미포함)
// 원본 배열은 변경되지 않음


// 방법 2 : 처음/끝 기준
array.slice(start)
// start : 시작 인덱스 (포함)


// 방법 3 : 음수 인덱스
arr.slice(음수)
// -1은 가장 끝

arr.slice(start, end)
// start : 시작 인덱스 (포함)
// end : 끝 인덱스 (포함)
JavaScript
const arr = [1, 2, 3, 4];

const sliced = arr.slice(1, 3);
console.log(sliced); // [2, 3]
console.log(arr); // [1, 2, 3, 4]

- splice : 원본 변경

JavaScript
arr.splice(start, deleteCount, ...items)
// start : 시작 인덱스
// deleteCount : 삭제할 개수
// ...items : 해당 위치에 추가할 값들
JavaScript
const arr = [1, 2, 3, 4];

arr.splice(1, 2); // index 1부터 2개 제거
console.log(arr); // [1, 4]
JavaScript
const arr = [1, 22, 4];

// 삭제만
arr.splice(1, 1);
console.log(arr); // [1, 4];


// 삽입만
arr.splice(1, 0, 99);
console.log(arr); // [1, 99, 4]

// 삭제 + 교체
arr.splice(1, 1, 100);
console.log(arr); // [1, 100, 4]

(4) sort

- 기본 정렬 (문자 기준)

JavaScript
// 대소문자 섞이지 않은 경우
const arr = ["c", "a", "b"];
arr.sort();

console.log(arr); // ["a", "b", "c"]
JavaScript
// 대소문자 섞인 경우 (오름차순)
const arr = ["c", "A", "b"];
arr.sort((a, b) => a.localeCompare(b));

console.log(arr); // ["A", "b", "c"]
JavaScript
// 대소문자 섞인 경우 (내림차순)
const arr = ["c", "A", "b"];
arr.sort((a, b) => b.localeCompare(a));

console.log(arr); // ["c", "b", "A"]

- 숫자 정렬 (비교 함수 필수)

JavaScript
// 오름차순 정렬
const nums = [10, 2, 30];
nums.sort((a, b) => a - b);

console.log(nums); // [2, 10, 30];
JavaScript
// 오름차순 정렬
const nums = [10, 2, 30];
nums.sort((a, b) => b - a);

console.log(nums); // [30, 10, 2];

(5) reverse

- 원본이 변경됨

JavaScript
const arr = [1, 2, 3];
arr.reverse();

console.log(arr); // [3, 2, 1]

(6) join

JavaScript
const arr = ["React", "is", "fun"];
const result = arr.join(" ");

console.log(result); // "React is fun"

3) 배열 변형 / 가공

(1) map

: 각 요소를 다른 값으로 바꾼 새 배열을 만든다.

JavaScript
const nums = [1, 2, 3];

const doubled = nums.map(n => n * 2);
console.log(doubled); // [2, 4, 6]

(2) filter

JavaScript
const nums = [1, 2, 3, 4];

const even = nums.filter(n => n%2 === 0);
console.log(even); // [2, 4]

(3) reduce

JavaScript
const nums = [1, 2, 3, 4];

const sum = nums.reduce((arr, cur) => arr + cur, 0);
console.log(sum); // 10

2) 2차원 배열

(1) 생성 방법

JavaScript
const board = Array.fron({length : 3}, () => 
	Array.from({length : 3}, () => 0)
);

console.log(board);
// [
//  [0,0,0],
//  [0,0,0],
//  [0,0,0]
// ]

(2) 행/열 순회

JavaScript
for (let i = 0; i < board.length; i++) {
  for (let j = 0; j < board[i].length; j++) {
    console.log(i, j, board[i][j]);
  }
}

(3) 좌표 기반 접근 (dx, dy 패턴)

JavaScript
const dx = [0, 0, -1, 1];
const dy = [-1, 1, 0, 0];

for (let d = 0; d < 4; d++) {
  const nx = x + dx[d];
  const ny = y + dy[d];

  if (nx >= 0 && ny >= 0 && nx < n && ny < m) {
    // 유효한 좌표
  }
}

2. 문자열 (String) - 입력 처리 & 파싱

1) 문자열 메서드

(1) split

: 문자열을 기준 문자로 나눠 배열로 변환

JavaScript
const input = "apple,banana,orange";
const arr = input.split(",");

console.log(arr); // ["apple", "banana", "orange"]
JavaScript
// 공백 기준 분리
const line = "10 20 30";
const nums = line.split(" ").map(Number);

console.log(nums); // [10, 20, 30]

(2) trim

: 문자열 앞뒤 공백 제거

JavaScript
const input = "   hello world   ";
console.log(input.trim()); // "hello world"

(3) replace, replaceAll

JavaScript
// replace (첫 번째만 변경)
const str = "a-b-c";
console.log(str.replace("-", "_")); // "a_b-c"
JavaScript
// replaceAll (전체 변경)
console.log(str.replaceAll("-", "_")); // "a_b_c"
JavaScript
// 정규식활용
const dirty = "1,000,000";
const clean = dirty.replace(/,/g, "");

console.log(clean); // "1000000"

(4) includes

: 문자열에 포함 여부 확인

JavaScript
const str = "frontend developer";

console.log(str.includes("dev")); // true
console.log(str.includes("back")); // false

(5) startsWith, endsWith

JavaScript
const file = "image.png";

console.log(file.startsWith("img")); // false
console.log(file.endsWith(".png"));  // true

(6) substring, slice

JavaScript
// substring(start, end)
const str = "abcdef";
console.log(str.substring(1, 4)); // "bcd"

2) 문자열 <-> 배열 패턴

(1) 한 글자씩 처리

- split("");

JavaScript
const str = "hello";
const chars = str.split("");

console.log(chars); // ["h", "e", "l", "l", "o"]

(2) 문자열 누적 vs 배열 push 후 join

JavaScript
// 문자열 누적

let result = "";

for (const ch of "abc") {
  result += ch.toUpperCase();
}

console.log(result); // "ABC"
JavaScript
// 배열에 모아서 joi
const temp = [];

for (const ch of "abc") {
  temp.push(ch.toUpperCase());
}

const result = temp.join("");
console.log(result); // "ABC"

3. 객체(Object) & 맵(Map)

1) Object (빈도수, 해시)

(1) {} 기본 사용법

JavaScript
const obj = {};

obj["apple"] = 1;
obj["banana"] = 2;

console.log(obj); // { apple: 1, banana: 2 }
JavaScript
obj.apple = 3;
console.log(obj.apple); // 3

(2) 키 존재 여부 확인

JavaScript
const obj = { a: 1 };

console.log("a" in obj); // true
console.log("b" in obj); // false
JavaScript
if (obj[key] === undefined) {
  // 키가 없음
}

2) Map

(1) 메서드 종류

- set

JavaScript
const map = new Map();
map.set("a", 1);
map.set("b", 2);

- get

JavaScript
console.log(map.get("a")); // 1

- has

JavaScript
console.log(map.has("a")); // true

- delete

JavaScript
map.delete("a");
console.log(map.has("a")); // false

(2) Object vs Map 차이

구분

Object

Map

키 타입

문자열만

모든 타입 가능

순서 보장

크기 확인

직접 계산

map.size

빈도수

?

??

성능

보통

대량 데이터에 유리

(3) 숫자/배열 키 사용

JavaScript
// Object는 자동 문자열 변환
const obj = {};
obj[1] = "one";
obj[[1,2]] = "array";

console.log(obj);
// { '1': 'one', '1,2': 'array' }
JavaScript
// Map은 타입 유지
const map = new Map();

map.set(1, "one");
map.set([1, 2], "array");

console.log(map.get(1));     // one
console.log(map.get([1,2])); // undefined (참조 다름)

3) 빈도수 / 카운팅 패턴

(1) 문자 빈도

JavaScript
// Object 버전
const str = "banana";
const count = {};

for(const ch of str) {
	count[ch] = (count[ch] || 0) + 1;
}

console.log(count);
// {b : 1, a : 3, n : 2}
JavaScript
// Map 버전
const map = new Map();

for(const ch of "banana"){
	map.set(ch, (map.get(ch) || 0) + 1);
}

console.log(map.get("a")); // 3

(2) 숫자 등장 횟수

JavaScript
const nums = [1, 2, 2, 3, 1, 2];
const freq = {}

for(const n of nums) {
	freq[n] = (freq[n] || 0) + 1;
}

console.logfreq);
// {1 : 2, 2 : 3, 3 : 1}
JavaScript
// reduce로 한 줄 처리

const freq = nums.reduce((acc, cur) => {
	acc[cur] = (acc[cur] || 0) + 1;
    return acc;
}, {});

4. Set - 중복 체크 & 방문 체크

1) add, has, delete

(1) add

JavaScript
const set = new Set();

set.add(1);
set.add(2);
set.add(2);

console.log(set); // Set {1, 2}

(2) has

JavaScript
console.log(set.has(1)); // true
console.log(set.has(3)); // false

(3) delete

JavaScript
set.delete(1);
console.log(set.has(1)); // false

(4) size

JavaScript
console.log(set.size);

2) 중복 제거

(1) 숫자 중복 제거

JavaScript
const nums = [1, 2, 2, 3, 3, 3];

const unique = [... new Set(nums)];
console.log(unique); // [1, 2, 3]

(2) 문자열 중복 제거

JavaScript
const str = "banana";

const uniqueStr = [... new Set(str)].join("");
console.log(uniqueStr); // "ban"

(3) 중복 개수 확인

JavaScript
const nums = [1, 1, 2, 2, 3];

const uniqueCount = new Set(nums).size;
console.log(uniqueCount); // 3

3) 방문 여부 체크 (그래프 / 시뮬레이션)

(1) 단순 방문 체크

JavaScript
const visited = new Set();

function visiti(node){
	if(visited.has(node)) return;
    viisted.add(node);
    
    console.log("방문 : ", node);
}

visit(1);
visit(2);
visit(1); // 무시됨

(2) 그래프 / DFS / BFS 방문 체크

JavaScript
const graph = {
	1 : [2, 3],
    2 : [4], 
    3 : [],
    4 : []
}

const visited = new Set();

function dfs(node) {
	if(visited.has(node)) return;
    
    visited.add(node);
    console.log(node);
    
    for(const next of graph[node]) {
    	dfs(next);
    }
}

dfs(1);

/*
1
2
4
3
*/

(3) 2차원 좌표 방문 체크

JavaScript
const visited = new Set();
const x = 2, y = 3;

const key = `${x},${y}`;

if(!visited.has(key)) {
	visited.add(key);
}

5. 수학(Math) & 숫자 처리

1) Math 객체

(1) Math.floor, Math.ceil, Math.round

- Math.floor : 내림

JavaScript
Math.floor(3.7); // 3
Math.floor(-3.2); // -4

- Math.ceil : 올림

JavaScript
Math.ceil(3.2); // 4
Math.ceil(-3.7); // -3

- Math.round : 반올림

JavaScript
Math.round(3.5); // 4
Math.round(3.4); // 3

(2) Math.abs

JavaScript
Math.abs(5);   // 5
Math.abs(-5);  // 5

const diff = Math.abs(a - b);

(3) Math.max, Math.min

JavaScript
Math.max(1, 3, 2); // 3
Math.min(1, 3, 2); // 1
JavaScript
// 배열에서 최대/최소 (스프레드 연산자와 세트로 기억)
const nums = [1, 5, 3];
Math.max(...nums); // 5
Math.min(...nums); // 1

(4) Math.pow, Math.sqrt

- Math.pow : 거듭 제곱

JavaScript
Math.pow(2, 3); // 8
// ES6
2 ** 3; // 8

- Math.sqrt : 제곱근

JavaScript
Math.sqrt(9);  // 3
Math.sqrt(2);  // 1.414...

2) 숫자 처리 패턴

(1) 자리수 분해

JavaScript
// 문자열 기반
const num = 1234;

const digits = String(num).split("").map(Number);
console.log(digits); // [1, 2, 3, 4]
JavaScript
// 수학적 분해
let n = 1234;
const digits = [];

while (n > 0) {
  digits.push(n % 10);
  n = Math.floor(n / 10);
}

digits.reverse();
console.log(digits); // [1, 2, 3, 4]

(2) 나머지 연산

JavaScript
// 짝수홀수
n % 2 === 0; // 짝수
n % 2 === 1; // 홀수

// 배수 체크
n % 3 === 0; // 3의 배수


// 순환 패턴 (인덱스)
const idx = i % arr.length;

6. 정렬 & 비교 로직

1) sort 심화

: sort는 원본 배열을 벼경하고, 비교함수가 없으면 문자열 기준 정렬을 한다.

(1) 숫자 정렬

JavaScript
// 오름차순
const nums = 10, 2, 30, 1];

nums.sort((a, b) => a - b);
console.log(nums); // [1, 2, 10, 30]

// 내림 차순
nums.sort((a, b) => b - a);
console.log(nums); // [30, 10, 2, 1];

(2) 문자열 정렬

JavaScript
const words = ["banana", "apple", "cherry"];
words.sort();

console.log(words); // ["apple", "banana", "cherry"]
JavaScript
// 대소문자 / 다국어 고려 시 localeCompare가 안전

// 오름차순
words.sort((a, b) => a.localeCompare(b));

// 내림차순
words.sort((a, b) => b.localeCompare(a));

(3) 객체 배열 정렬

JavaScript
const users = [
	{name : "Kim", age : 30},
	{name : "Lee", age : 20},
	{name : "Park", age : 25},
];

// 숫자 기준 (예시로 나이)
users.sort((a, b) => a.age - b.age);
console.log(users);
/*
[
  { name: "Lee", age: 20 },   // 가장 나이가 적음
  { name: "Park", age: 25 }, // 중간
  { name: "Kim", age: 30 }   // 가장 나이가 많음
]
*/

// 문자열 기준 (예시로 이름)
users.sort((a, b) => a.name.localeCompare(b.name));
console.log(users);
/*
[
  { name: "Kim", age: 30 },  // K
  { name: "Lee", age: 20 },  // L
  { name: "Park", age: 25 } // P
]
*/

(4) 다중 조건 정렬

JavaScript
// 1차 조건 -> 같으면 2차 조건
users.sort((a, b) => {
  if (a.age !== b.age) {
    return a.age - b.age;
  }
  return a.name.localeCompare(b.name);
});
JavaScript
// 1차 조건 (점수), 2차 조건 (이름)

const students = [
  { name: "Kim", score: 90 },
  { name: "Lee", score: 90 },
  { name: "Park", score: 80 }
];

students.sort((a, b) => {
  if (a.score !== b.score) {
    return b.score - a.score; // 점수 내림
  }
  return a.name.localeCompare(b.name); // 이름 오름
});

console.log(students);
/*
[
  { name: "Kim", score: 90 },  // 점수 90 (동점) → 이름 K
  { name: "Lee", score: 90 },  // 점수 90 (동점) → 이름 L
  { name: "Park", score: 80 }  // 점수 80
]
*/

| 결론

JavaScript 기본기는 결국 “어떤 자료구조를 쓰고, 어떤 메서드를 고를 수 있느냐”에서 갈린다. 이 포스팅의 목표는
“외우는 문서”가 아니라 문제를 만났을 때 바로 떠올릴 수 있는 기준표를 만드는 것이다.