update
24.12.30. - set 추가
24.12.23 - map 수정(매개변수 사용추가)
24.12.14 - slice 수정
24.12.13 - sort 수정
- 참고
arr.length : 배열의 길이. 1부터 시작
...arr : 배열을 풀어야 할 때 배열 이름 앞에 ...을 붙이세요
function solution(N) {
return [...String(N)].reduce((sum, digit) => sum + +digit, 0);
}
배열 선언 및 초기화
- 배열 선언
- let arr = []; // 빈 배열 let numbers = [1, 2, 3, 4, 5]; // 숫자 배열 let mixed = [1, "hello", true, { key: "value" }, [1, 2]]; // 혼합형 배열
- Array 생성자 사용
- let arr = new Array(); // 빈 배열 let numbers = new Array(10); // 길이가 10인 빈 배열 let predefined = new Array(1, 2, 3); // [1, 2, 3]
기본 배열 메서드
1. 요소 접근 및 변경
let arr = [10, 20, 30];
console.log(arr[0]); // 10
arr[1] = 25; // 배열의 두 번째 요소 변경
console.log(arr); // [10, 25, 30]
2. 배열 길이 확인
let arr = [1, 2, 3];
console.log(arr.length); // 3
3. 요소 추가/제거
- push: 끝에 요소 추가
- pop: 끝에서 요소 제거
- unshift: 앞에 요소 추가
- shift: 앞에서 요소 제거
let arr = [1, 2, 3];
arr.push(4); // [1, 2, 3, 4]
arr.pop(); // [1, 2, 3]
arr.unshift(0); // [0, 1, 2, 3]
arr.shift(); // [1, 2, 3]
배열 순회
for 루프
let arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
for...of
for (let value of arr) {
console.log(value);
}
forEach
arr.forEach((value, index) => {
console.log(index, value);
});
길이가 2인 배열을 값으로 가지는 배열
[[1,2],[22,44], ... ]
function solution(sizes) {
let [mW, mH] = [0, 0];
// 값을 ([w, h])로 뽑아낼 수 있음
sizes.forEach(([w, h]) => {
if (w < h) [w, h] = [h, w]; // 가로와 세로를 정렬
mW = Math.max(mW, w); // 최대 가로값
mH = Math.max(mH, h); // 최대 세로값
});
return mW * mH;
}
배열 변환 및 필터링(새로운 배열 만들기)
map: 각 요소를 변환하여 새 배열 생성
arr.map(function(element, index, array){ }, this);
콜백함수 function()은 각 배열 요소에 대해 호출되며, map() 메소드는 언제나 현재의 element와 그것의 index, 그리고 전체 array 객체를 해당 요소에 전달합니다.
this인수는 콜백함수 내부에서 사용되게 됩니다. 기본적으로 이 값은 undefined입니다. 예를 들어, this값을 숫자 80으로 변경하는 방법은 다음과 같습니다:
let arr = [2, 3, 5, 7]
arr.map(function(element, index, array){
console.log(this) // 80
}, 80);
대부분의 경우 나머지는 무시하고 콜백 함수 내부의 element 인수만 사용합니다.
let numbers = [1, 2, 3];
let squared = numbers.map(num => num ** 2);
console.log(squared); // [1, 4, 9]
filter: 조건을 만족하는 요소만 필터링
let numbers = [1, 2, 3, 4];
let evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
reduce: 누적 계산
뒤에 붙은 0은 acc의 초기값
let numbers = [1, 2, 3, 4];
let sum = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // 10
https://miiingo.tistory.com/365
repeat : 주어진 문자열의 지정된 수만큼 복사본을 포함하는 새 문자열을 반환합니다.
매개변수는 양의 정수여야 합니다.
// "반복문자열"repeat(count)
"abc".repeat(2); // 'abcabc'
이런 식으로도 사용 가능
function solution(n) {
return "수박".repeat(Math.floor(n / 2)) + (n % 2 === 1 ? "수" : "");
}
console.log(solution(3)); // "수박수"
배열 정렬
sort: 배열 정렬
- 기본적으로 요소를 문자열로 취급하며 유니코드 순서대로 정렬합니다.
- 다양한 상황에서 compareFunction을 활용하여 맞춤 정렬이 가능합니다.
- 기본 정렬은 문자열 기준이며 유니코드 순서대로 수행됩니다.
- 숫자 정렬 시 compareFunction을 반드시 사용해야 합니다.
- 2차원 배열과 객체는 특정 요소나 속성을 기준으로 맞춤 정렬이 가능합니다.
- 숫자나 객체를 정렬할 때는 compareFunction 사용.
- 문자열 정렬 시 localeCompare()를 활용하면 대소문자 구분 없는 정렬도 가능.
1. 기본 문법
arr.sort([compareFunction]);
- compareFunction 생략 시: 요소들은 문자열로 취급되어 유니코드 순서로 정렬.
- compareFunction 사용 시: 정렬 순서를 직접 정의 가능 .
- 반환 값이 > 0: a는 b 뒤에 위치
- 반환 값이 < 0: a는 b 앞에 위치
- 반환 값이 0: 순서 변경 없음
https://ashen99.tistory.com/497
2. 문자열 정렬
1. 오름차순 정렬
let arr = ["a", "d", "z", "p", "j", "c", "k", "s"];
arr.sort();
console.log(arr); // ['a', 'c', 'd', 'j', 'k', 'p', 's', 'z']
2. 내림차순 정렬
let strArray = ["BA", "BB", "AA", "AB", "CB", "CA"];
strArray.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));
console.log(strArray); // ["CB", "CA", "BB", "BA", "AB", "AA"]
let strArray = ["BA", "BB", "AA", "AB", "CB", "CA"];
strArray.sort((a, b) => b.localeCompare(a));
console.log(strArray); // ["CB", "CA", "BB", "BA", "AB", "AA"]
파라미터
- compareFunction(옵션): 정렬 순서를 정의하는 함수.
- a, b를 입력받아 다음을 결정:
- 음수 반환: a가 b보다 앞.
- 양수 반환: b가 a보다 앞.
- 0 반환: 순서 유지.
- a, b를 입력받아 다음을 결정:
리턴값
- 원본 배열(arr)을 정렬하며, 정렬된 배열을 리턴.
- 주의: 원본 배열이 변경됨.
3. 내림차순, 대문자가 소문자보다 앞에 오게 정렬
사용자 지정 정렬 함수를 사용
const arrStr = ['a', 'B', 'C', 'd', 'E', 'f'];
arrStr.sort((a, b) => {
// 알파벳 내림차순으로 정렬
if (a.toLowerCase() > b.toLowerCase()) return -1;
if (a.toLowerCase() < b.toLowerCase()) return 1;
// 대소문자 우선 순위 설정 (대문자가 소문자보다 앞에)
if (a < b) return -1;
if (a > b) return 1;
return 0; // 동일한 경우
});
console.log(arrStr);
// 출력 예: ['f', 'd', 'a', 'E', 'C', 'B']
- toLowerCase()로 문자를 소문자로 변환한 후 알파벳 순서를 기준으로 내림차순 정렬.
- 동일한 알파벳일 경우, ASCII 값 비교를 통해 대문자가 소문자보다 앞에 오도록 설정.
- JavaScript에서 대문자는 소문자보다 작은 ASCII 값을 가짐.
4. 대소문자 구분 없이 문자정렬
대소문자 구분 없는 문자열 정렬은 localeCompare 활용.
오름차순
const words = ['Banana', 'apple', 'Cherry'];
words.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(words); // ['apple', 'Banana', 'Cherry']
내림차순
words.sort((a, b) => b.toLowerCase().localeCompare(a.toLowerCase()));
console.log(words); // ['Cherry', 'Banana', 'apple']
3. 숫자 정렬
숫자, 객체 정렬 시 비교 함수(compareFunction) 필요.
1. 한 자리 숫자 정렬 (문자열 취급)
let arr = [1, 4, 6, 8, 5, 3, 7];
arr.sort();
console.log(arr); // [1, 3, 4, 5, 6, 7, 8]
2. 오름차순 정렬
- a - b가 음수면 a가 b보다 앞.
let arr = [13, 46, 52, 36, 75, 3];
arr.sort((a, b) => a - b);
console.log(arr); // [3, 13, 36, 46, 52, 75]
3. 내림차순 정렬
- b - a를 이용.
let arr = [13, 46, 52, 36, 75, 3];
arr.sort((a, b) => b - a);
console.log(arr); // [75, 52, 46, 36, 13, 3]
4. 2차원 배열 정렬
- 특정 인덱스를 기준으로 정렬
const arr = [
[10, 2],
[7, 8],
[3, 3],
[-1, 3],
[99, 99],
[-10, 10],
];
arr.sort((a, b) => a[1] - b[1]); // 두 번째 요소 기준 오름차순
console.log(arr);
// [ [ 10, 2 ], [ 3, 3 ], [ -1, 3 ], [ 7, 8 ], [ -10, 10 ], [ 99, 99 ] ]
- 내림차순 정렬
const arr = [
[2, 9, 2],
[-1, -2, -3],
[0, 3, 3],
[12, -1, 6],
[9, 10, 11],
];
arr.sort((a, b) => b[2] - a[2]); // 세 번째 요소 기준 내림차순
console.log(arr);
// [ [ 9, 10, 11 ], [ 12, -1, 6 ], [ 0, 3, 3 ], [ 2, 9, 2 ], ... ]
5. 객체 정렬
- 객체의 특정 속성을 기준으로 정렬
- 숫자, 객체 정렬 시 비교 함수(compareFunction) 필요.
예: 가격(price)을 기준으로 오름차순
const items = [
{ name: 'apple', price: 50 },
{ name: 'banana', price: 30 },
{ name: 'cherry', price: 70 }
];
items.sort((a, b) => a.price - b.price);
console.log(items);
// [
// { name: 'banana', price: 30 },
// { name: 'apple', price: 50 },
// { name: 'cherry', price: 70 }
// ]
내림차순
items.sort((a, b) => b.price - a.price);
console.log(items);
// [
// { name: 'cherry', price: 70 },
// { name: 'apple', price: 50 },
// { name: 'banana', price: 30 }
// ]
reverse: 배열 순서 뒤집기
let arr = [1, 2, 3];
console.log(arr.reverse()); // [3, 2, 1]
배열 탐색
find: 조건을 만족하는 첫 번째 요소 찾기
let arr = [5, 12, 8, 130, 44];
let found = arr.find(num => num > 10);
console.log(found); // 12
findIndex : 조건을 만족하는 첫 번째 요소의 인덱스 찾기
조건을 만족하는 요소가 없으면 -1을 반환합니다.
let arr = [10, 20, 30, 40];
let index = arr.findIndex(num => num > 25);
console.log(index); // 2 (30은 25보다 큼)
console.log(arr.findIndex(num => num > 50)); // -1 (조건을 만족하는 요소 없음)
indexOf / includes
indexOf : 배열이나 문자열에서 특정 값을 찾고, 그 첫 번째 발생 위치의 인덱스를 반환합니다.
찾는 값이 없으면 -1을 반환합니다.
includes : 배열이나 문자열에서 특정 값을 찾고, 있으면 true 없으면 false를 방환합니다.
let arr = [1, 2, 3, 4];
console.log(arr.indexOf(3)); // 2 일치하는 값의 자리를 반환
console.log(arr.includes(5)); // false 포함여부 boolen값으로 반환
lastIndexOf : 배열이나 문자열에서 특정 값을 찾고, 마지막으로 발생한 위치의 인덱스를 반환합니다.
찾는 값이 없으면 -1을 반환합니다.
배열 예제
let arr = [10, 20, 30, 20];
console.log(arr.lastIndexOf(20)); // 3 (마지막 20의 인덱스)
console.log(arr.lastIndexOf(50)); // -1 (50은 배열에 없음)
문자열 예제
let str = "hello world, hello!";
console.log(str.lastIndexOf("hello")); // 13 (마지막 "hello"의 시작 인덱스)
console.log(str.lastIndexOf("JavaScript")); // -1 (존재하지 않음)
Array.some()
some() 메서드는 배열의 요소 중 적어도 하나가 주어진 판별 함수를 통과하는지 확인합니다.
조건을 만족하는 요소가 하나라도 있으면 true를 반환, 없다면 false를 반환합니다.
배열 자체를 변경하지 않습니다.
// 화살표 함수
some((element) => { /* … */ })
some((element, index) => { /* … */ })
some((element, index, array) => { /* … */ })
// 콜백 함수
some(callbackFn)
some(callbackFn, thisArg)
// 인라인 콜백 함수
some(function (element) { /* … */ })
some(function (element, index) { /* … */ })
some(function (element, index, array) { /* … */ }, thisArg)
매개변수:
- callbackFn:
- 배열의 각 요소에 대해 실행되는 함수.
- 인자:
- element: 현재 요소.
- index: 현재 요소의 인덱스.
- array: some()을 호출한 배열.
- thisArg (선택):
- callbackFn을 실행할 때 사용할 this 값.
반환값:
- 배열의 요소 중 하나라도 callbackFn에서 참(true)을 반환하면 true.
- 모든 요소가 거짓(false)일 경우 false.
특징
- 순회 멈춤:
조건을 만족하는 요소를 찾으면 바로 순회를 멈추고 true를 반환합니다. - 희소 배열 지원:
값이 없는 빈 슬롯은 무시됩니다. - 배열의 원본 유지:
배열을 변경하지 않습니다. - 일반 객체에서도 사용 가능:
배열이 아닌 객체에서도 Array.prototype.some을 호출하여 사용할 수 있습니다. (길이와 키 속성만 있으면 됨)
// 조건 테스트:
[2, 5, 8, 1, 4].some((x) => x > 10); // false
[12, 5, 8, 1, 4].some((x) => x > 10); // true
// 값 포함 여부 확인:
const fruits = ["apple", "banana", "mango"];
fruits.some((fruit) => fruit === "banana"); // true
fruits.some((fruit) => fruit === "grape"); // false
// 불리언 변환:
const TRUTHY_VALUES = [true, "true", 1];
function getBoolean(value) {
return TRUTHY_VALUES.some((t) => t === value);
}
getBoolean("true"); // true
getBoolean("false"); // false
// 희소 배열 사용:
console.log([1, , 3].some((x) => x === undefined)); // false
// 배열이 아닌 객체에서 사용:
const arrayLike = { length: 3, 0: "a", 1: "b", 2: "c" };
Array.prototype.some.call(arrayLike, (x) => x === "b"); // true
배열 병합 및 슬라이싱
concat: 배열 병합
let arr1 = [1, 2]; let arr2 = [3, 4];
let merged = arr1.concat(arr2);
console.log(merged); // [1, 2, 3, 4]
slice: 배열의 일부를 추출
let arr = [1, 2, 3, 4];
let sliced = arr.slice(1, 3);
console.log(sliced); // [2, 3]
- 문자열에서 slice
- slice() 메서드는 문자열의 일부를 추출하여 새로운 문자열로 반환합니다.
- 원래 문자열은 수정되지 않습니다.
- 추출 범위를 벗어나는 인덱스가 사용되더라도 오류는 발생하지 않고 빈 문자열 또는 가능한 범위를 반환.
slice(indexStart)
slice(indexStart, indexEnd)
indexStart
- 추출할 시작 위치를 지정합니다(0부터 시작하는 인덱스).
- indexStart >= str.length이면 빈 문자열 반환.
- 양수: 문자열의 시작에서부터 해당 위치까지 계산.
- 음수: 문자열의 끝에서부터 뒤로 계산.(-1부터 시작)
indexEnd(생략 가능)
- 추출을 멈출 위치를 지정합니다(포함되지 않음).
- 양수: 문자열의 시작에서 해당 위치까지 계산.
- 음수: 문자열의 끝에서부터 뒤로 계산. (-1부터 시작)
- 생략하면 문자열의 끝까지 추출.
1. 기본 사용법
const str = "The morning is upon us.";
console.log(str.slice(1, 8)); // "he morn"
console.log(str.slice(4, -2)); // "morning is upon u"
console.log(str.slice(12)); // "is upon us."
console.log(str.slice(30)); // "" (빈 문자열)
2. 음수 인덱스 사용
const str = "The morning is upon us.";
console.log(str.slice(-3)); // "us."
console.log(str.slice(-3, -1)); // "us"
console.log(str.slice(11, -7)); // " is u"
console.log(str.slice(-11, -7)); // " is "
console.log(str.slice(0, -1)); // "The morning is upon us"
console.log(str.slice(4, -1)); // "morning is upon us"
배열 slice
- 배열 또는 유사 배열 객체의 일부를 추출하여 얕은 복사본으로 반환하는 도구
- 원본 배열은 절대 수정되지 않습니다.
- 새로운 배열 객체로, 원본 배열에서 선택된 요소들을 반환합니다.
1. 기본
slice()
slice(start)
slice(start, end)
- start (선택사항): 추출 시작 인덱스(0 기반). 음수일 경우, 배열 끝에서부터 계산.
- end (선택사항): 추출 종료 인덱스. 포함되지 않음. 음수일 경우 배열 끝에서부터 계산.
const fruits = ["Apple", "Banana", "Orange", "Mango"];
// 기본
console.log(fruits.slice(1, 3)); // ['Banana', 'Orange']
// end 매개변수 생략
console.log(fruits.slice(2)); // ['Orange', 'Mango']
// 음수 인덱스 사용
console.log(fruits.slice(-2)); // ['Orange', 'Mango']
// 양수 및 음수 인덱스 혼합
console.log(fruits.slice(1, -1)); // ['Banana', 'Orange']
2. 객체 배열 슬라이싱
const car = { color: "red" };
const array = [car, "other"];
const newArray = array.slice(0, 1);
car.color = "blue";
console.log(newArray[0].color); // 'blue'
배열 유사 객체 슬라이싱
const arrayLike = { length: 3, 0: "a", 1: "b", 2: "c" };
console.log(Array.prototype.slice.call(arrayLike)); // ['a', 'b', 'c']
배열 변환 유틸리티
const slice = Function.prototype.call.bind(Array.prototype.slice);
function convertArgsToArray() {
return slice(arguments);
}
console.log(convertArgsToArray(1, 2, 3)); // [1, 2, 3]
3. 희소 배열 처리
console.log([1, , 3, 4].slice(1, 3)); // [empty, 3]
splice: 배열 수정 (요소 추가/삭제)
배열에서 요소를 추가하거나 제거하거나 교체하는 데 사용
- 배열을 직접 수정합니다(원본 배열 변경).
- 추가와 삭제를 동시에 수행할 수 있습니다.
- 성능: .splice()는 배열 크기에 따라 성능에 영향을 줄 수 있습니다. 특히, 많은 요소가 포함된 배열에서 중간 요소를 제거하면 뒤의 모든 요소가 이동합니다.
- 원본 배열이 변경되므로 불변성이 중요한 경우 slice()나 다른 메서드를 고려해야 합니다.
array.splice(start, deleteCount, item1, item2, ...);
- start (필수):
- 변경을 시작할 배열의 인덱스를 지정합니다.
- 양수: 해당 인덱스부터 시작.
- 음수: 배열의 끝에서부터 역으로 계산.
- deleteCount (선택):
- 배열에서 제거할 요소의 개수를 지정합니다.
- 0이면 아무 것도 삭제하지 않습니다(추가만 수행).
- 생략하면 start부터 배열의 끝까지 모든 요소를 삭제합니다.
- item1, item2, ... (선택):
- 배열에 추가할 요소들을 지정합니다.
- 삭제 대신 새 요소를 삽입하거나 기존 요소를 교체할 때 사용됩니다.
let arr = [1, 2, 3, 4];
arr.splice(1, 2, 5, 6); // 1번 인덱스에서 2개 제거, 5와 6 추가
console.log(arr); // [1, 5, 6, 4]
1. 요소 삭제
let fruits = ["apple", "banana", "cherry", "date"];
let removed = fruits.splice(1, 2); // 인덱스 1부터 2개 제거
console.log(fruits); // ["apple", "date"]
console.log(removed); // ["banana", "cherry"]
2. 요소 추가
let fruits = ["apple", "date"];
fruits.splice(1, 0, "banana", "cherry"); // 인덱스 1에 추가
console.log(fruits); // ["apple", "banana", "cherry", "date"]
3. 요소 교체
let fruits = ["apple", "banana", "cherry"];
fruits.splice(1, 1, "grape"); // 인덱스 1의 요소를 "grape"로 교체
console.log(fruits); // ["apple", "grape", "cherry"]
4. 끝에서부터 요소 삭제
let fruits = ["apple", "banana", "cherry"];
fruits.splice(-1, 1); // 끝에서부터 1개 제거
console.log(fruits); // ["apple", "banana"]
배열 수정
스프레드 문법과 객체.assign을 활용해 조건부로 속성을 병합하는 방식
export const updatePlayer = (req, res) => {
try {
const { name } = req.params;
const { speed, shooting, grade } = req.body;
if (!name) return handleError(res, 400, "Player name is required.");
const player = players.find((p) => p.name === name);
if (!player) return handleError(res, 404, "Player not found.");
Object.assign(player, { ...(speed && { speed }), ...(shooting && { shooting }), ...(grade && { grade }) });
res.status(200).json(player);
} catch {
handleError(res, 500, "Failed to update player");
}
};
코드 동작 설명
- 요청에서 파라미터와 데이터 추출:
- req.params에서 name을 가져옵니다. 이는 URL 경로의 파라미터입니다.
- req.body에서 speed, shooting, grade 값을 추출합니다. 이는 클라이언트가 보낸 JSON 데이터입니다.
const { name } = req.params; const { speed, shooting, grade } = req.body;
- 유효성 검사:
- name이 없으면 에러를 반환합니다.
- players 배열에서 해당 이름의 플레이어를 찾습니다.
- 찾지 못하면 404 에러를 반환합니다.
if (!name) return handleError(res, 400, "Player name is required."); const player = players.find((p) => p.name === name); if (!player) return handleError(res, 404, "Player not found.");
- 업데이트 수행:
- Object.assign을 사용하여 기존 player 객체를 업데이트합니다.
- 조건부로 제공된 데이터(speed, shooting, grade)만 병합됩니다.
- 이를 위해 스프레드 문법을 사용해 개별 속성을 분리하고, 조건이 참일 때만 객체로 추가합니다.
Object.assign( player, { ...(speed && { speed }), ...(shooting && { shooting }), ...(grade && { grade }) } );
- 응답 반환:
- 업데이트된 player 객체를 JSON 형식으로 반환합니다.
- 상태 코드는 200입니다.
res.status(200).json(player);
- 에러 처리:
- 실행 중 문제가 발생하면 상태 코드 500과 함께 에러 메시지를 반환합니다.
catch { handleError(res, 500, "Failed to update player"); }
핵심 코드 분석
1. Object.assign
Object.assign은 하나 이상의 객체를 병합해 기존 객체를 업데이트하거나 새로운 객체를 생성할 때 사용됩니다.
Object.assign(target, source1, source2, ...);
- target: 병합의 대상이 되는 객체.
- source: 병합할 속성들을 가진 객체.
이 코드에서 Object.assign(player, {...})는 player 객체에 새로운 속성들을 추가하거나 기존 속성을 덮어씁니다.
2. 스프레드 문법 ...
...는 객체나 배열의 요소를 "펼쳐서" 새로운 객체/배열을 생성하는 문법입니다.
조건부 속성 추가
...(speed && { speed })
- 조건 speed가 truthy일 때만 { speed: speed }라는 객체를 생성하고, 이를 펼쳐서 병합합니다.
- 만약 speed가 undefined거나 null이라면 아무 것도 병합되지 않습니다.
전체 코드
{
...(speed && { speed }), // speed가 있으면 { speed: speed }
...(shooting && { shooting }), // shooting이 있으면 { shooting: shooting }
...(grade && { grade }) // grade가 있으면 { grade: grade }
}
- 결과적으로 speed, shooting, grade 중 클라이언트가 제공한 값만 병합됩니다.
3. 배열과 객체의 동작
players는 배열이므로, players.find를 통해 특정 조건에 맞는 객체 참조를 가져옵니다.
이후 Object.assign으로 이 참조된 객체의 내용을 직접 변경합니다. 배열 자체는 수정되지 않고, 해당 객체만 업데이트됩니다.
장점
- 조건부 업데이트:
- 제공된 속성만 업데이트하며, 불필요한 데이터 변경을 방지합니다.
- 간결성:
- 스프레드 문법과 Object.assign으로 복잡한 업데이트를 한 줄로 처리합니다.
- 원본 객체 수정:
- player는 players 배열의 원본 참조이기 때문에, Object.assign으로 업데이트하면 배열의 해당 객체도 즉시 반영됩니다.
스프레드 문법 대신 if문을 사용
export const updatePlayer = (req, res) => {
const { name } = req.params;
const { speed, shooting, grade } = req.body;
const player = players.find((p) => p.name === name);
if (!player) return res.status(404).json({ message: "Player not found" });
if (speed) player.speed = speed;
if (shooting) player.shooting = shooting;
if (grade) player.grade = grade;
res.json(player);
};
Object.assign 없이 새로운 객체를 생성하여 기존 객체를 업데이트
1. 스프레드 문법을 사용
스프레드 문법을 사용하여 원래 객체와 업데이트할 속성들을 병합하여 새 객체를 생성합니다.
const updatedPlayer = {
...player,
...(speed && { speed }),
...(shooting && { shooting }),
...(grade && { grade }),
};
- ...player: 기존 객체의 모든 속성을 복사합니다.
- 조건부 병합:
- speed && { speed }처럼 값이 존재할 때만 속성을 추가합니다.
- 기존 player는 유지되고, updatedPlayer라는 새 객체가 생성됩니다.
2. Object.keys와 forEach 사용
수동으로 객체를 순회하며 조건에 맞는 속성만 추가합니다.
const updatedPlayer = { ...player }; // 기존 객체 복사
['speed', 'shooting', 'grade'].forEach((key) => {
if (req.body[key]) updatedPlayer[key] = req.body[key];
});
- 속성 리스트: 업데이트할 가능성이 있는 속성 목록을 배열로 정의.
- 조건부 추가: req.body에 값이 있는 속성만 새로운 객체에 추가.
3. for...in 반복문 사용
for...in 문을 사용하여 동적으로 속성을 검사하고 추가할 수 있습니다.
const updatedPlayer = { ...player }; // 기존 객체 복사
for (const key in req.body) {
if (['speed', 'shooting', 'grade'].includes(key) && req.body[key]) {
updatedPlayer[key] = req.body[key];
}
}
- 유효성 검사:
- key가 허용된 속성(speed, shooting, grade)인지 확인.
- 값이 존재할 때만 추가.
4. reduce를 활용한 함수형 방식
reduce를 사용하여 유효한 속성만 새로운 객체에 추가합니다.
const updatedPlayer = ['speed', 'shooting', 'grade'].reduce((acc, key) => {
if (req.body[key]) acc[key] = req.body[key];
return acc;
}, { ...player });
- 초기값: player의 복사본을 초기값으로 사용.
- 조건부 추가: req.body에 값이 있는 속성만 acc 객체에 추가.
5. 깊은 병합을 위한 유틸 함수 활용
여러 단계로 중첩된 객체를 병합하려면 커스텀 함수를 사용할 수 있습니다.
function merge(target, source) {
const result = { ...target };
for (const key in source) {
if (source[key] !== undefined) {
result[key] = source[key];
}
}
return result;
}
const updatedPlayer = merge(player, { speed, shooting, grade });
- merge 함수:
- 기존 객체(target)과 새 데이터(source)를 병합.
- 값이 undefined가 아닌 경우에만 병합.
비교
방법 장점 단점
스프레드 문법 | 간결하고 가독성이 높음 | 업데이트할 속성이 많으면 코드가 길어질 수 있음 |
Object.keys + forEach | 동적으로 처리 가능, 코드 관리 용이 | 반복문을 사용해 약간 복잡해질 수 있음 |
for...in 반복문 | 유연하게 속성 검사 가능 | 배열 순회보다 조금 더 느릴 수 있음 |
reduce | 함수형 방식으로 간결한 처리 가능 | 초심자에게는 약간 난해할 수 있음 |
유틸 함수 사용 | 재사용 가능, 유연한 병합 가능 | 커스텀 함수 정의가 필요 |
set
Set은 JavaScript에서 고유한 값을 저장할 수 있는 데이터 구조입니다. 중복이 자동으로 제거되며, 배열과 유사한 메서드를 제공합니다.
주요 메서드 및 사용법
- 생성
- const mySet = new Set();
- 값 추가
- mySet.add(1); mySet.add(2); mySet.add(1); // 중복된 값은 추가되지 않음 console.log(mySet); // Set { 1, 2 }
- 값 삭제
- mySet.delete(1); console.log(mySet); // Set { 2 }
- 값 포함 확인
- console.log(mySet.has(2)); // true console.log(mySet.has(3)); // false
- 크기 확인
- console.log(mySet.size); // 1
- 반복
- for (let value of mySet) { console.log(value); }
- 배열 변환
- const myArray = [...mySet]; // Set -> Array console.log(myArray); // [2]
특징
- 중복 제거: 중복된 값이 자동으로 제거됩니다.
- 정렬 없음: 삽입된 순서를 유지하지만, 정렬은 지원하지 않습니다.
활용 예시: 중복 제거
const arr = [1, 2, 2, 3, 4, 4];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1, 2, 3, 4]
문자열, 숫자 ↔ 배열
join: 배열을 문자열로 결합
let arr = ["Hello", "World"];
console.log(arr.join(" ")); // "Hello World"
split은 문자열(String)을 특정 구분자를 기준으로 분리하여 배열(Array)로 반환하는 메서드입니다. 주로 문자열을 배열로 변환할 때 사용됩니다.
string.split(separator, limit)
- separator: 문자열을 분리하는 기준이 되는 구분자 (필수).
- 구분자로 문자열이나 정규식을 사용할 수 있습니다.
- separator를 지정하지 않으면 문자열 전체가 하나의 요소로 포함된 배열을 반환합니다.
- limit: 분리 후 반환할 배열의 최대 길이 (옵션).
- 이 값을 지정하면 배열의 요소 개수가 limit을 초과하지 않습니다.
기본
// 기본 예제
let str = "apple,banana,cherry";
let arr = str.split(",");
console.log(arr); // ["apple", "banana", "cherry"]
// 공백을 기준으로 분리
let sentence = "Hello World! How are you?";
let words = sentence.split(" ");
console.log(words); // ["Hello", "World!", "How", "are", "you?"]
//구분자를 빈 문자열로 설정 : 문자열의 각 문자를 개별 요소로 나눌 수 있습니다.
let str = "hello";
let chars = str.split("");
console.log(chars); // ["h", "e", "l", "l", "o"]
limit 사용
let str = "one,two,three,four,five";
let arr = str.split(",", 3); // 3개의 요소까지만 반환
console.log(arr); // ["one", "two", "three"]
정규식을 사용한 분리
- 정규식을 사용하면 더 복잡한 패턴으로 문자열을 분리할 수 있습니다.
let str = "apple123banana456cherry";
let arr = str.split(/\d+/); // 숫자를 기준으로 분리
console.log(arr); // ["apple", "banana", "cherry"]
구분자를 지정하지 않는 경우
- 구분자를 생략하면 문자열 전체를 하나의 배열 요소로 반환합니다.
let str = "hello world";
let arr = str.split();
console.log(arr); // ["hello world"]
응용: 문장 단위 분리
let text = "This is sentence one. Here is sentence two. And finally, sentence three.";
let sentences = text.split(". ");
console.log(sentences);
// ["This is sentence one", "Here is sentence two", "And finally, sentence three."]
참고
문자 정렬 : https://yooneeee.tistory.com/17
'내일배움 정리 > JS 문법 공부' 카테고리의 다른 글
화살표함수(작성중) (0) | 2024.12.03 |
---|---|
형변환, 숫자의 진법변환 (0) | 2024.12.03 |
Math메서드(method) (1) | 2024.12.03 |
연산 기호 - 같다, 같지 않다 (==, ===, !=, !== (0) | 2024.12.03 |
input 받기 (0) | 2024.12.03 |