.slice(시작 인덱스, 끝 인덱스);
여기선 인자 2개가 들어갔지만, slice 메소드는 필요에 따라 인자를 최소 1개만 쓸 수도 있다.
- 첫번째 인자 : 배열의 index의 시작점
- 두번째 인자 : 배열의 index의 끝점
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// [-3][-2][-1]
let arr1 = arr.slice(3, 5); // [3]부터 [4]까지
console.log(arr1); // [4, 5]
let arr2 = arr.slice(-1); // 배열의 제일 끝 요소부터 리턴
console.log(arr2); // [9]
let arr3 = arr.slice(0, -2); // [0]부터 [-2] 앞까지
console.log(arr3); // [1, 2, 3, 4, 5, 6, 7]
let arr4 = arr.slice(-2); // 배열의 제일 끝 요소부터 그 이전까지만 리턴
console.log(arr4); // [8, 9]
function saveNumberTwo(prisoners) {
let temp = prisoners.slice(-2); // [[1,2], [0,0]]
let answer = temp[0][1]; // temp[0]=[1,2] 중에서도 인덱스[1]=2
return answer; // 2
}
let prisoners = [[0, 1],[1,2],[0,0]];
saveNumberTwo(prisoners); // 2
.splice(수정할 인덱스 번호, 삭제할 인덱스 원소 개수, 배열에 추가할 요소)
ex: arr.splice(5, 3, 'Hello', 'banana');
- 인덱스 [5]부터 변경이 됨.
- [5]의 다음 요소 3개가 삭제가 됨.
- [5]의 다음 요소부터 "Hello", "banana" 의 원소가 추가 됨.
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.splice(5, 3, 'apple', 'banana');
// 인덱스 [5]부터 요소 3개를 제거 후, 'apple'과 'banana'를 추가
console.log(arr);
// [1, 2, 3, 4, 5, "apple", "banana", 9]
// [0][1][2][3][4]
let myArr = ['사과', '빵', '우유', '과자', '감자'];
// '우유'를 삭제하고 싶음
myArr.splice(2, 1); // 인덱스 [2]부터 요소 1개를 제거
console.log(myArr); // ['사과', '빵', '과자', '감자']
let myArr = ['사과', '빵', '우유', '과자', '감자'];
// '우유'를 '두유'로 바꾸고 싶음
myArr.splice(2, 1, '두유'); // 인덱스 [2]부터 요소 1개를 제거하고, '두유'로 변경
console.log(myArr); // ['사과', '빵', '두유', '과자', '감자']
let newArr = arr.filter(callback(currentValue[element, index, [array]]) {
}[, thisArg]);
- callback : 3개의 인자 (element, index, array) 를 가지는 조건값에 대한 함수
- element : 처리할 현재 요소
- index : 현재 인덱스
- array : filter를 호출한 배열
- thisArg : callback을 생행 할 때 this로 사용하는 값
let numbers = [10, 4, 32, 17, 5, 2];
let result = numbers.filter((value)=> value > 10); // 10보다 큰 원소만 골라서 새로운 배열을 리턴
console.log(result); // [32, 17]
💡 .filter()안에 들어간 변수명(value)은 임의로 지어도 됨.
Q. fruits 라는 배열이 있다. 'ap'가 들어간 과일들로 이루어진 새로운 배열을 filter()를 이용하여 반환하라. 결과는 아래와 같아야 한다.
[ 'apple', 'grapes' ]
function filtered(value) {
return fruits.filter(value => value.includes('ap'));
}
console.log(filtered());
▶ Feedback
let result 선언해서 푸는 것이 깔끔함.
Try 1)
오답
function filtered (value) {
return value.includes('ap');
}
let result = fruits.filter(filtered);
console.log(result); // 출력 자체는 정상 ['apple', 'grapes']
▶ Feedback
문제 의도 파악 miss: includes()를 이용해 'ap'포함된 과일을 filter 메소드를 이용해서 return 하길 원하는 것
Sol ) 함수 코드 블럭 안에서 return 해주기 위해 filter를 이용한 구문도 함수 안으로 들어가야 함.
Try 2)
function filtered () {
let result = fruits.filter(includeAp)
return result
}
function includeAp(texts){
return texts.includes("ap")
}
console.log(filtered());
▶ Feedback
filter 메소드 안의 함수를 밖으로 빼버리는 방법으로 작동 문제는 없으나 가독성 떨어짐.
Sol) callback 호출 사용하여 깔끔하게 정리
🔥 Model Answer
function filtered () {
let result = fruits.filter((value) => value.includes('ap'));
return result;
}
console.log(filtered()); // expected output: ["apple", "grapes"]
function filtered(value) { // 2 - Arr 배열의 복제본이 함수에 전달
let value2 = value.includes('ap'); // 3 - 복제본의 원소들 중 'ap'가 포함된 문자열 검색하여 새로운 변수 value2에 담는다
return value2; // 4 - 새로운 변수 value2 리턴
}
let result = Arr.filter(filtered); // 1 - filter()를 이용하여 콜백함수 호출 -> 리턴된 value2 값을 새로운 변수 result에 담는다
console.log(result); // 5 - result값 반환
true
, 없으면 false
를 반환하는 메소드.arr.includes(valueToFind[, fromIndex]);
매개변수
- valueToFind : 탐색할 요소
*참고: 문자나 문자열을 비교할 때, includes()는 대소문자를 구분함.- fromIndex (Optional) : 배열에서 searchElement 검색을 시작할 위치.
음의 값은 array.length + fromIndex의 인덱스를 asc로 검색. 기본값 : 0
var a = [1, 2, 3, 4, 5, 1, 2, 3];
var b = a.includes(3); // 배열 a에 3이 있는지 T/F
console.log(b); // true
var c = a.includes(6); // 배열 a에 6이 있는지 T/F
console.log(c); // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
arr.indexOf(searchElement[, fromIndex]);
매개변수
- searchElement : 배열에서 찾을 요소
- fromIndex (Optional) : 검색을 시작할 인덱스
인덱스가 배열의 길이보다 크거나 같은 경우 -1이 반환되므로 배열이 검색되지 않음. 제공된 인덱스 값이 음수이면 배열 끝에서부터의 오프셋 값으로 사용됨.
*참고 : 제공된 인덱스가 음수이면 배열은 앞에서 뒤로 검색됨. 계산된 인덱스가 0보다 작으면 전체 배열이 검색됨. 기본값 : 0 (전체 배열 검색)
array.concat([value1[, value2[, ...[, valueN]]]]);
- 배열 또는 값
- 만약 value1 ~ valueN 인자를 생략하면 기존 배열의 얕은 복사본을 반환.
- valueN (optional)
*참고: 배열이나 값을 이어붙여도 원본은 변하지 않으며, 새로운 배열이나 원본 배열을 조작해도 서로 영향을 받지 않습니다.
const alpha = ['a', 'b', 'c'];
// 배열 2개 이어붙이기
const arr = [1, [2, 3]];
alpha.concat(arr); // [ 'a', 'b', 'c', 1, [ 2, 3 ] ]
// 배열 3개 이어붙이기
alpha.concat(arr);
alpha.concat(1, [2, 3]); // [ 'a', 'b', 'c', 1, 2, 3 ]
// 중복된 숫자나 글자를 가진 배열을 합칠 때 --> 요소의 중복과 상관없이 배열 합쳐줌.
const numbers = [1, 2, 3];
const numbers2 = [3, 4, 5];
numbers.concat(numbers2); // [ 1, 2, 3, 3, 4, 5 ]
Q. 파스타와 피자의 재료가 배열로 나타나있다. 중복된 재료를 뺀 전체 재료의 배열 한 개를 만들어라. 결과는 아래와 같아야 한다.
// 중복된 재료를 뺀 전체 재료
[ 'tomato', 'basil', 'onion', 'chicken', 'cheese', 'olive', 'beef' ]
오답
let pasta = ['tomato', 'basil', 'onion','chicken'];
let pizza = ['tomato', 'cheese', 'onion','olive','beef'];
function totalIngredients () {
let result = pasta.concat(pizza);
let erase = result.filter(('tomato', 0) => result.indexOf('tomato') === 0);
}
console.log(totalIngredients());
▶ Feedback
arrow function 사용 miss, return 사용 안 함.
Sol ) let 사용해서 새로운 변수 선언해주고 result.filter((el,index) =>
result.indexOf(el) === index) 사용해야 함.
let pasta = ['tomato', 'basil', 'onion','chicken'];
let pizza = ['tomato', 'cheese', 'onion','olive','beef'];
function totalIngredients () {
let result = pasta.concat(pizza);
let newResult = result.filter((word, index) =>
result.indexOf(word) === index);
return newResult;
}
console.log(totalIngredients());
new Set([iterable]);
매개변수
- iterable : 반복 가능한 객체가 전달된 경우, 그 요소는 모두 새로운 Set에 추가됨. 만약 매개변수를 명시하지 않거나 null을 전달하면, 새로운 Set은 비어 있는 상태가 됨.
// array 의 경우 문제 없다.
let employeeId = ['a12', 'e7', 'c2', 'a12'];
// set은 각 요소가 유일해야 한다.
let employeeId2 = new Set(['a12', 'e7', 'c2', 'a12']);
console.log(employee2); // {'a12', 'e7', 'a12'}
.size
: array의 length와 동일
.add
: array의 push와 동일 * 참조형 데이터는 동일한 요소 추가 가능
.clear
: empty the Set
.delete
: 특정 요소를 삭제
.entries
: Map처럼, iterable을 반환한다. key-value pair를 반환하지만 key와 value는 같다.
.forEach
.has
: 특정 요소가 존재하는지 확인한다.
.keys
, .values
arrow function을 가장 많이 사용할 때는 callback 함수로 사용할 때다. callback 함수는 인자로 전달되는 함수를 의미한다. array 반복문으로 사용되는 메서드로는 map과 forEach가 있다.
arr.map(callback(currentValue[, index[, array]])[, thisArg]);
매개변수
- callback : 새로운 배열 요소를 생성하는 함수
- currentValue : 처리할 현재 요소
- index (optional) : 처리할 현재 요소의 인덱스
- array (optional) : map()을 호출한 배열
- thisArg (optional) : callback을 실행할 때 this로 사용되는 값
var array = [1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1, 9.1, 10.1];
// 일반함수로 map 메서드 표현
var array10 = array.map(function (elements){
return elements * 10;
});
console.log(array10);
// [11, 21, 31, 41, 51, 61, 71, 81, 91, 101]
// 화살표함수로 map 메서드 표현
var array20 = array.map((el) => el*10);
console.log(array20);
// [11, 21, 31, 41, 51, 61, 71, 81, 91, 101]
💡 map VS filter
공통점: 기존 배열은 건드리지 않고 요소들을 순회한 후 새로운 배열을 리턴하는 메소드
차이점: map은 콜백 함수가 적용된 새 요소, filter는 조건문을 만족한 요소들을 반환
arr.forEach(callback(currentvalue[, index[, array]])[, thisArg]);
매개변수
- callback : 각 요소에 대해 실행할 함수
- currentValue : 처리할 현재 요소
- index (optional) : 처리할 현재 요소의 인덱스
- array (optional) : forEach()를 호출한 배열
- thisArg (optional) : callback을 실행할 때 this로 사용할 값
forEach는 for 대신 사용하는 반복문이다. map과의 큰 차이는 map
이 요소가 수정된 새로운 배열이 return
되었다면, forEach
는 아무것도 return하는 것이 없다
. 그래서 forEach로 전달되는 callback 함수에서도 return하는 것이 없다.
let startWithNames = [];
let names = ['a', 'ab', 'cbb', 'ada'];
names.forEach(el => {
if (el.startsWith('a')) {
startWithNames.push(el);
}
});
let hasC = false;
let arr = ['a', 'b', 'c', 'd'];
arr.forEach(el => {
if (el === 'c') {
hasC = true;
return;
}
});
forEach도 함수이므로, 중간에 반복문을 탈출하고 싶으면 return; 을 해주면 된다. 만약 forEach에서 현재 index를 알고 싶으면 두 번째 인자로 받을 수 있다.
let idxOfC = -1;
let arr = ['a', 'b', 'c', 'd'];
arr.forEach((el, idx) => {
if (el === 'c') {
idxOfC = idx;
return;
}
});