Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
347 changes: 347 additions & 0 deletions Part2-1팀 /3주차-1/전성현.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
# 배열과 메소드
## 배열 요소 추가·제거 메소드
맨 끝 요소 추가 `arr.push(...items)`
맨 끝 요소 제거 `arr.pop()`
맨 앞 요소 제거 `arr.shift()`
맨 앞 요소 추가 `arr.unshift(...items)`

### splice
기존 배열에 요소를 추가·삭제·교체를 모두 할 수 있는 메소드

```js
arr.splice(index[, deleteCount, elem1, ..., elemN])
```
`index` 작업할 첫 번째 요소
`deleteCount` 제거할 요소의 개수
`elem1, ..., elemN` 배열에 추가할 요소

배열 요소 추가하기
```js
let arr = ["I", "study", "JavaScript"];

// 인덱스 2부터 0개의 요소를 삭제하고, "complex"와 "language"를 추가
arr.splice(2, 0, "complex", "language");

alert(arr); // I study complex language JavaScript
```

배열 요소 삭제하기
```js
let arr = ["I", "study", "JavaScript"];

// 인덱스 1부터 요소 1개를 제거
arr.splice(1, 1);

// I JavaScript
alert(arr); // I JavaScript
```

배열 요소 교체하기
```js
let arr = ["I", "study", "JavaScript", "right", "now!"];

// 인덱스 0부터 3개의 요소를 지우고, 이 자리를 다른 요소로 교체
arr.splice(0, 3, "Let's", "dance");

alert(arr) // Let's dance right now!
```

`splice`는 삭제된 요소를 배열로 반환

#### ⚠️ 음수 인덱스 사용도 가능
배열 관련 메소드에는 음수 인덱스를 사용할 수 있고, 마이너스 부호 앞 숫자는 배열 끝에서부터 센 요소 위치를 나타냄


### slice
```js
arr.slice([start], [end])
```
`start` 인덱스부터 `end` 바로 앞 인덱스까지의 요소를 복사하여 새로운 배열로 반환

### concat
```js
arr.concat(arg1, arg2, ...)
```
기존 배열 요소를 사용해 새로운 배열을 만들거나 기존 배열에 요소를 추가할 때 사용
아규먼트에는 배열이나 값이 오고, 개수 제한이 없음

```js
let arr = [1, 2];

// arr의 모든 요소와 [3,4]의 모든 요소를 한데 모은 새로운 배열을 생성
alert( arr.concat([3, 4]) ); // 1,2,3,4

// arr의 모든 요소와 [3,4]의 모든 요소, [5,6]의 모든 요소를 모은 새로운 배열을 생성
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6

// arr의 모든 요소와 [3,4]의 모든 요소, 5와 6을 한데 모은 새로운 배열을 생성
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
```

### forEach
각각의 배열 요소를 주어진 함수를 통해 실행이 가능
```js
// Apple, Strawberry, Grape 순으로 alert창을 띄움
["Apple", "Strawberry", "Grape"].forEach(alert);
```


## 배열 탐색하기
### indexOf, lastIndexOf, includes
`arr.indexOf(item, from)`는 인덱스 `from`부터 시작해서 요소 `item`을 찾는데, 요소를 발견하면 해당 요소의 인덱스를 반환하고, 발견하지 못하면 -1을 반환
`arr.lastIndexOf(item, from)`는 위 메소드와 동일하게 동작하고, 검색을 뒤에서부터 시작
`arr.includes(item, from)`는 인덱스 `from`부터 시작해서 `item`이 있는지 검색하고, 해당 요소를 찾으면 true를 반환
```js
let arr = [1, 0, false];

alert( arr.indexOf(0) ); // 1
alert( arr.indexOf(false) ); // 2
alert( arr.indexOf(null) ); // -1

alert( arr.includes(1) ); // true
```
⚠️ 위 메소드들은 요소를 찾을 때 완전 항등 연산자 `===`를 사용한다는 점에 유의
```js
const arr = [NaN];
alert( arr.indexOf(NaN) ); // -1 (완전 항등 비교 === 는 NaN엔 동작하지 않으므로 0이 출력되지 않음)
alert( arr.includes(NaN) ); // true (NaN 여부를 확인 완료)
```
`includes`는 `indexOf`, `lastIndexOf`와는 다르게 `NaN`을 제대로 처리


### find, findIndex
객체로 이루어진 배열에서 특정 조건에 부합하는 객체를 배열 내에서찾을 때 사용
```js
let result = arr.find(function(item, index, array) {
...
});
```
`item` 배열에서 호출할 요소
`index` 요소의 인덱스
`array` `find()`가 호출된 배열 자기 자신


요소 전체를 함수가 순차적으로 호출
조건에 일치하는 요소를 찾으면 `true`를 반환, 반복을 멈추고 해당 요소를 반환
조건에 해당하는 요소가 없으면 `undefined`를 반환


`id`와 `name` 프로퍼티를 가진 사용자 객체가 각각의 요소인 배열 내에서 `id == 1` 조건을 충족하는 사용자 객체를 찾기
```js
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];

let user = users.find(item => item.id == 1);

alert(user.name); // John
```
보통 `find` 내의 함수 파라미터가 `item` 하나인 경우가 가장 많고, `index`, `array` 파라미터는 잘 사용되지 않음
`arr.findIndex`는 `find`와 동일하게 동작하는데, 조건에 맞는 요소를 반환하는 게 아닌 해당 요소의 인덱스를 반환하고, 조건에 맞는 요소가 없으면 `-1`이 반환됨

### filter
객체로 이루어진 배열에서 조건을 충족하는 요소가 여러 개일 때 사용하는 메소드
`filter`는 `find`와 유사하지만, 조건에 맞는 요소가 포함된 배열 전체를 반환
```js
let results = arr.filter(function(item, index, array) {
...
});
```
조건을 충족하는 요소는 `results`에 순차적으로 더해지고, 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환됨


## 배열을 변형시키는 메소드
### map
배열 요소 전체를 대상으로 함수를 호출하고, 그 결과를 배열로 반환
요소 대신 새로운 값을 반환
```js
let result = arr.map(function(item, index, array) {
...
});
```

각 요소(문자열)의 길이를 출력
```js
let lengths = ["Apple", "Avocado", "Banana"].map(item => item.length);
alert(lengths); // 5,7,6
```

### sort
배열의 요소를 정렬해주고, 배열 원본 자체가 변경됨
메소드를 호출하면 재정렬된 배열이 반환되는데, 이미 arr 자체가 수정되었기 때문에 반환값은 잘 사용되지 않음
```js
let arr = [ 1, 2, 15 ];

// arr 내부가 재정렬됨
arr.sort();

alert(arr); // 1, 15, 2
```
배열 요소가 1, 15, 2로 정렬되었는데, 요소는 문자열로 변환된 후 재정렬되기 때문
문자열 비교는 *사전 편집 순*으로 진행되어 2는 15보다 큰 값으로 취급됨 (`"2" > "15"`)


❓ *사전 편집 순*
알파벳 사전에서 단어를 정렬하는 방식과 유사하게 문자 하나씩 유니코드(UTF-16) 코드 포인트 값을 기준으로 비교한다는 의미


기본 정렬 기준 대신 새로운 정렬 기준을 만드려면 `arr.sort()`에 새로운 함수를 넘겨줘야 함
파라미터로 넘겨주는 함수는 반드시 두 개의 값을 비교하고 반환값도 있어야 함
```js
function compare(a, b) {
if (a > b) return 1; // 첫 번째 값이 두 번째 값보다 큰 경우
if (a == b) return 0; // 두 값이 같은 경우
if (a < b) return -1; // 첫 번째 값이 두 번째 값보다 작은 경우
}
```
배열 요소를 숫자 오름차순 기준으로 정렬하기
```js
function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}

let arr = [ 1, 2, 15 ];

arr.sort(compareNumeric);

alert(arr); // 1, 2, 15
```
배열에는 숫자, 문자열, 객체 등이 들어갈 수 있는데, 각 요소의 타입이 다르면 정렬 기준을 정의하는 정렬 함수가 필요
정렬 함수를 파라미터로 넘겨주지 않으면 `sort`는 사전 편집 순으로 요소를 정렬

#### ⚠️ 정렬 함수는 어떤 숫자든 반환이 가능
정렬 함수의 반환값에는 제약이 없음
정렬 함수에서 양수를 반환하면 첫 번째 파라미터가 두 번째 파라미터보다 크다는 것과 음수를 반환하면 첫 번째 파라미터가 두 번째 파라미터보다 작다는 것을 아래처럼 간결하게 만들 수 있음
```js
let arr = [ 1, 2, 15 ];

arr.sort(function(a, b) { return a - b; });

alert(arr); // 1, 2, 15
```

### reverse
배열의 요소를 역순으로 정렬
```js
let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert(arr); // 5, 4, 3, 2, 1
```
재정렬된 배열을 반환

### split, join
`split`은 긴 문자열을 구분자를 기준으로 나눠서 배열로 반환
다음 코드는 쉼표와 공백을 합친 문자열을 구분자로 사용
```js
let names = 'Jun, Hwan, Min';

let arr = names.split(', ');

for (let name of arr) {
alert( `${name}에게 보내는 메시지` ); // Jun에게 보내는 메시지
}
```
`split` 메소드는 두 번째 인수를 숫자로 받고, 그 숫자만큼 배열의 길이를 제한
```js
let arr = 'Jun, Hwan, Min, Kyu'.split(', ', 2);

alert(arr); // Jun, Hwan
```

`join`은 `split`과 반대로 배열의 모든 요소를 합친 후 하나의 문자열로 반환
```js
let arr = ['Jun, Hwan, Min'];

let str = arr.join(';'); // 배열의 모든 요소를 세미콜론(;)을 사용해 하나의 문자열로 합침

alert( str ); // Jun;Hwan;Min
```

### reduce, reduceRight
배열을 기반으로 하나의 값을 도출할 때 사용
```js
let value = arr.reduce(function(accumulator, item, index, array) {
...
}, [initial]);
```
`accumulator` 이전 함수 호출의 결과
`initial` 함수 최초 호출 시 사용되는 초깃값을 나타냄(옵션)
`item` 현재 배열 요소
`index` 요소의 위치
`array` 배열


이전 함수 호출 결과는 다음 함수를 호출할 때 첫 번째 파라미터로 사용
첫 번째 파라미터는 앞서 호출된 함수들의 결과가 누적되어 저장되고, 마지막 함수까지 호출된 값의 누적치를 반환


배열의 모든 요소를 더한 값 구하기
```js
let arr = [1, 2, 3, 4, 5];

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15
```
함수 최초 호출 시 `reduce`의 마지막 파라미터인 0이 초깃값으로 `sum`에 할당
`current`에는 배열의 첫 번째 요소인 1이 할당
따라서 함수의 결과는 `sum`과 `current`의 합인 1
이런 과정이 계속되어 0 + 1 + 2 + 3 + 4 + 5 = 15로 결과가 도출


## 배열 여부 확인하기
자바스크립트에서 배열은 독립된 자료형이 아닌 객체형에 속함
```js
alert(typeof {}); // object
alert(typeof []); // object
```
`typeof`로는 일반 객체와 배열을 구분할 수 없음

### Array.isArray
배열인지 아닌지 구별하고, 배열이면 `true`를, 배열이 아니면 `false`를 반환
```js
alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
```


## 배열 메소드와 thisArg
함수를 호출하는 대부분의 배열 메소드(`sort`를 제외한 `find`, `filter`, `map` 등)는 `thisArg`라는 매개변수를 옵션으로 받을 수 있음
```js
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
...
```
`thisArg`는 선택적으로 사용할 수 있는 마지막 파라미터
`thisArg`는 `func`의 `this`가 됨
```js
let army = {
minAge: 18,
maxAge: 27,
canJoin(user) {
return user.age >= this.minAge && user.age < this.maxAge;
}
};

let users = [
{age: 16},
{age: 20},
{age: 23},
{age: 30}
];

// army.canJoin 호출 시 참을 반환해주는 user 찾기
let soldiers = users.filter(army.canJoin, army);

alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23
```
`thisArgs`에 `army`를 지정하지 않고 `users.filter(army.canJoin)`를 사용했다면 `army.canJoin`은 단독 함수처럼 취급
함수 본문 내 `this`는 `undefined`가 되어 에러가 발생