배열

5o_hyun·2022년 2월 7일
0
post-thumbnail

배열이란?

배열 ( array ) 은 여러개의 값을 순차적으로 나열한 자료구조이다.
배열은 사용 빈도가 매우 높은 가장 기본적인 자료구조이다.
자바스크립트에 배열이라는 타입은 존재하지않으며, 배열은 객체 타입이다.

const arr = ['apple','banana','orange'];

arr[0] // apple
arr[1] // banana
arr[2] // orange

arr.length // 3
typeof arr // object

배열이 가지고 있는 값을 요소 ( element ) 라고 한다. 자바스크립트의 모든 값은 요소가 될 수 있다. ( 객체, 함수, 배열 등 )

배열의 요소는 자신의 위치를 나타내는 인덱스 ( index ) 를 갖으며 0부터 시작한다.

배열은 요소의 개수, 즉 배열의 길이를 나타내는 length 프로퍼티를 갖는다.

따라서, 배열은 인덱스와 length 프로퍼티를 갖기때문에 for 문을 통해 순차적으로 요소에 접근할 수 있다.
( 배열은 순서가 있기때문에 순회할 수 있다. )

for(let i = 0; i < arr.length; i++){
	console.log(arr[i]); // apple, banana, orange
}

희소배열이란, 배열의 요소가 연속적으로 위치하지 않고 일부가 비어있는 배열을 말한다.
일반적인 배열의 length는 배열의 길이와 일치하지만, 희소배열은 length와 배열 요소의 개수가 일치하지 않는다.
희소배열의 length는 희소배열의 실제 요소 개수보다 언제나 크다.

자바스크립트는 희소배열을 문법적으로 허용하지만 희소배열은 사용하지 않는 것이 좋다.
배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 가장 좋다.

// 희소배열
const arr2 = [1,2, ,4];

// 희소배열의 length는 요소의 개수와 다르다.
console.log(arr2.length); // 4
console.log(arr2); // 1, 2, empty , 4

배열 만들기

1. 배열 생성

객체와 마찬가지로 배열도 다양한 생성방식이 있다.

1-1. 배열 리터럴

가장 일반적이고 간편한 배열 생성 방식은 배열 리터럴을 사용하는 것이다.
배열리터럴은 쉼표로 구분하여 대괄호 [ ] 로 묶는다.

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

// 희소배열
const arr2 = [1, , 3]; 
console.log(arr2.length); // 3
console.log(arr2); // [1, empty, 3]

1-2. Array 생성자 함수

Object 생성자 함수로 객체를 생성할 수 있듯이 Array 생성자 함수로 배열을 생성 할 수도 있다.
빈 값의 새 배열을 생성한다.
즉, 생성된 배열은 희소배열이다. length 프로퍼티 값은 0은 아니지만 실제로 배열의 요소는 존재하지 않는다.

const arr = new Array(10);
console.log(arr.length); // 10
console.log(arr); // [empty, empty, ... , empty]

1-3. Array.of

ES6에서 도입된 Array.of 메서드는 전달된 인수를 요소로 갖는 배열을 생성한다.
즉, 넘길 인자를 요소로 써서 생성한다.

Array.of(1); // [1]
Array.of(1,2,3); // [1, 2, 3]
Array.of('string'); // ['string']

1-4. Array.from

ES6에서 도입된 Array.from 메서드는 유사 배열 객체를 인수로 전달받아 배열로 변환하여 반환한다.

// 유사배열객체를 변환하여 배열을 생성 (여기서 유사배열객체는 {length : 2, 0 : 'a', 1 : 'b'} 이다.)
Array.from({length : 2, 0 : 'a', 1 : 'b'}); // ['a', 'b']

// 문자열을 변환하여 배열을 생성
Array.from('cat'); // ['c', 'a', 't']

2. 배열 요소의 참조

배열의 요소를 참조할 때에는 대괄호 [ ] 표기법을 사용한다.
인덱스로 접근하는데, 인덱스는 값을 참조할 수 있다는 의미에서 객체의 프로퍼티 키와 같은 역할을 한다.

const arr = [1, 2];
console.log(arr[0]); // 1
console.log(arr[1]); // 2
// 존재하지 않는 요소를 참조하면 undefined가 반환된다.
console.log(arr[2]); // undefined

3. 배열 요소 추가

객체에 프로퍼티를 동적으로 추가 할 수 있는거처럼 배열의 요소도 동적으로 추가 할 수 있다.
존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가된다. 이떄 length 프로퍼티 값은 자동으로 갱신된다.

const arr = [0];

// 배열 요소 추가
arr[1] = 1;

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

// length보다 더 큰 값 추가시 나머지는 희소배열이 된다.
arr[100] = 100;
console.log(arr); // [0, 1, empty x 98 , 100]

만약 현재 배열의 length 프로퍼티 값보다 큰 인덱스로 새로운 요소를 추가하면 희소배열이 된다.

4. 배열 요소 삭제

배역의 특정요소를 삭제하기위해서는 delete 연산자를 사용한다.
이 떄 특정요소는 희소배열이 되며, length값은 변하지 않는다. 따라서 희소배열을 만드는 delete연산자는 사용하지 않는 것이 좋다.

const arr = [1, 2, 3];

// 배열 요소 삭제
delete arr[1];
console.log(arr); // [1, empty, 3]
console.log(arr.length); // 3 --> length 에는 영향을 주지 않음 

배열 메서드

배열 메서드는 결과물을 반환하는 패턴이 2가지다.

  • 원본배열을 직접 변경하는 메서드
  • 원본배열을 직접 변경하지않고 새로운 배열을 생성하여 반환하는 메서드

예를 들면, 크게 push 원본배열 변경 메서드 / concat 새로운 배열 반환 메서드 가 있다.

const arr = [1];

// push 는 원본 배열을 직접 변경한다.
arr.push(2);
console.log(arr); // [1, 2]

// concat 은 원본을 건드리지않고 새로운 배열을 반환한다.
const result = arr.concat(3);
console.log(arr); // [1, 2]
console.log(result); // [1, 2, 3]

1. Array.isArray

.isArray : 배열이면 true, 배열이 아니면 false 반환

Array.isArray([]); // true
Array.isArray([1,2]); // true
Array.isArray(); // false
Array.isArray(true); // false

2. Array.prototype.indexOf

.indexOf : 요소가 있냐 없냐
요소가 있으면 인덱스번호를 반환한다. 없으면 -1 반환

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

// 배열에서 요소 2를 검색하여 첫번째로 검색한 인덱스를 반환
arr.indexOf(2); // 1

// 배열에서 요소 4가 없으므로 -1 반환
arr.indexOf(4); // -1

// 두번째인수는 검색을 시작할 인덱스다. 두번째인수를 생략하면 처음부터 검색한다.
arr.indexOf(2, 2); // 3

3. Array.prototype.includes

indesOf 메서드 대신 ES7에서 도입된 .includes 메서드를 쓰면 true false 로만 나와서 가독성이 더 좋다.

const arr = ['apple', 'banana', 'orange'];
arr.includes('apple'); // true

// 요소 유무에 따라 추가도 가능하다

// melon이 없으면 melon을 추가해라 
if(!arr.includes('melon')) {
	arr.push('melon');
}
console.log(arr); // ['apple', 'banana', 'orange', 'melon']

4. Array.prototype.push

5. Array.prototype.pop

.push : 요소추가 , 원본 변경, 제일 끝에 추가한다.
.pop : 요소삭제 , 원본 변경 , 제일 끝이 삭제된다.

const arr = [1, 2];
arr.push(3);
console.log(arr); // [1, 2, 3] 뒤에서 pop을 했기때문에 원본이 변경되어 pop과 동시에 [1,2] 가 된다.
arr.pop();
console.log(arr); // [1, 2]

이렇듯, push 와 pop 메서드가 제일 끝에것이 바뀌므로 이를 사용해 스택을 쉽게 구현할 수 있다.
스택은 데이터를 마지막에 밀어넣고 마지막에 밀어넣은 데이터를 먼저 꺼내는 후입선출 ( LIPO - Last In First Out ) 자료구조이다.
스택에 데이터를 밀어넣는 것을 push , 스택에서 데이터를 꺼내는것을 pop 이라고 한다.


6. Array.prototype.unshift

7. Array.prototype.shift

.unshift : 요소추가, 원본 변경, 제일 앞에 추가된다
.shift : 요소삭제, 원본 변경, 제일 앞이 삭제된다

const arr = [1, 2];
arr.unshift(3, 4);
console.log(arr); // [3, 4, 1, 2] 뒤에서 shift를 했기때문에 원본이 변경되어 shift와 동시에 [4, 1, 2]가 됨
arr.shift();
console.log(arr); // [4, 1, 2]

이렇듯 unshift와 shift 메서드가 제일 앞에것이 바뀌므로 이를 사용해 큐를 쉽게 구현할 수 있다.
큐는 데이터를 마지막에 밀어넣고, 처음 데이터 즉 가장 먼저 밀어넣은 데이터를 먼저 꺼내는 선입선출 ( FIFO = First In First Out ) 방식의 자료구조이다.
스택은 언제나 마지막에 밀어넣은 최신 데이터를 취득하지만 큐는 언제나 데이터를 밀어넣은 순서대로 취득한다.


8. Array.prototype.concat

.concat : 인수로 전달된 값을 원본배열의 마지막요소로 추가해 새로운 배열 반환
인수로 전달한 값이 배열일 경우 해체하여 새로운 배열의 요소로 추가한다.

const a = ['a','b','c'];
const b = [1, 2];
console.log(a.concat(b)); // ['a', 'b', 'c', 1, 2]

9. Array.prototype.splice

.splice : 원본 배열의 중간에 요소를 추가하거나 제거할 때 사용 , 원본 변경

const arr = ['a','b','c'];
arr.splice(0,1);
console.log(arr); // ['b','c']

const arr2 = ['a','b','c'];
arr2.splice(1,1);
console.log(arr2); // ['a', 'c']

// 뒤에서도 뺄 수 있다 
const arr3 = ['a','b','c'];
arr3.splice(-1,1);
console.log(arr3); // ['a', 'b']

10. Array.prototype.slice

.slice : 배열을 잘라서 새로운 배열로 반환
이 때 생성된 복사본은 얕은 복사 이다.

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

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

11. Array.prototype.join

.join : 배열을 문자열로 반환, 기본구분은 콤마(,) 다른 구분자로 연결 가능

const arr = [1,2,3,4,5];
console.log(arr.join()); // 1,2,3,4,5
console.log(arr.join('')); // 12345
console.log(arr.join(':')); // 1:2:3:4:5

12. Array.prototype.flat

.flat : 배열을 깨준다. = 배열을 평탄화 해줌

const arr = ['a','b','c',[1,2]];
console.log(arr.flat()); // ['a','b','c',1,2]

배열 고차함수

1. Array.prototype.sort

.sort : 요소를 정렬, 기본적으로는 오름차순, 원본 변경

const arr = ['c','a','b'];
console.log(arr.sort()); // ['a','b','c']

const arr2 = ['사과','오렌지','바나나'];
console.log(arr2.sort()); // ['바나나','사과','오렌지']

sort 메서드는 기본적으로 오름차순으로 정렬된다.
문자열, 영어는 물론 한글도 마찬가지로 정렬된다. 하지만 숫자는 예외이다.

따라서 숫자를 정렬할 때에는 sort 메서드에 정렬순서를 정의하는 비교함수를 인수로 전달해야한다.
--> 콜백함수를 써야한다.

const points = [1,40,100,59,68];
// 숫자 배열의 오름차순
points.sort((a, b) => a - b);
console.log(points); // [1,40,59,68,100]

// 숫자 배열의 내림차순
points.sort((a, b) => b - a); 
console.log(points); // [100,68,59,40,1]

2. Array.prototype.forEach

.forEach : 자신의 내부에서 반복문을 실행 해 for문을 대체할 수 있는 고차함수

const numbers = [1,2,3];
const result = [];

// 이전에 썼던 for문으로 배열 순회
for (let i = 0; i < numbers.length; i++){
	result.push(numbers[i] ** 2);
}
console.log(result); // [1,4,9]

// forEach메서드는 numbers배영의 모든 요소를 순회하면서 콜백함수를 반복호출
numbers.forEach(item => result.push(item ** 2));
console.log(result); // [1,4,9]

여기서 numbers.forEach ( item,index ... // 이 부분은 원하는걸로 가능 ) => { // 여기를 단순반복 });


3. Array.prototype.map

.map : 콜백 함수의 반환값들로 구성된 새로운 배열을 반환

const numbers = [1,4,9];
const result = numbers.map((item) => item + 1);
console.log(result); // [2,5,10]

console.log(numbers === result); // false

4. Array.prototype.filter

.filter : 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환

const arr = [1,2,3,4,5];
const odd = arr.filter(item => item % 2);
console.log(odd); // [1,3,5]

console.log(arr === odd); // false

5. Array.prototype.reduce

.reduce : 배열의 모든 요소를 순회하여 인수로 전달받은 콜백함수를 반복호출하고, 콜백함수의 반환값을 다음 순회 시 콜백함수의 첫번째 인수로 전달하면서 콜백함수를 호출 하여 하나의 결과값을 만들어 반환

const arr = [1,2,3];

const result = arr.reduce((accumulator, currentValue) => accumulator + currentValue, 0);

console.log(result);



// 쉽게 표현하자면, 
const arr = [1,2,3];

const result = arr.reduce((a, b) => a + b, 0);

console.log(result);

뒤에 있는 0 이 초기 값이고, acc ( a ) 가 0 cur ( b ) 가 1 이 되어 0 + 1 = 1 의 콜백함수 반환값 1을 다음인자로 넣는다.
따라서 다음은 acc ( a ) 가 1 cur ( b ) 가 2 이 되어 1 + 2 = 3 의 콜백함수 반환값 3을 다음인자로 넣는다.
위와 같이 다음은 acc ( a ) 가 3 cur ( b ) 가 3 이 되어 3 + 3 = 6 이고 다음 인자가 없기때문에 result의 값은 최종적으로 6이 된다.


6. Array.prototype.some

7. Array.prototype.every

.some : 콜백함수의 반환값이 단 한번이라도 참이면 true, 모두 거짓이면 false 반환 --> AND 조건

.every : 콜백함수의 반환값이 모두 참이면 true, 단 하나라도 거짓이면 false 반환 --> OR 조건

var arr = [{name: '소현', age: 10},{name: '나영', age: 8}, {name: '미지', age: 3}];

console.log(arr.some((item)=> item.age>5)); //true
console.log(arr.some((item)=> item.age>10)); //false 모두 거짓

console.log(arr.every((item)=> item.age>1)); // true 모두 참
console.log(arr.every((item)=> item.age>5)); // false

기존ES5의 indexOf가 배열내의 특정 값을 찾는데에 사용되었다면, ES6에서 추가된 find, findIndex는 callback 함수를 통해서 좀 더 복잡한 조건의 검색이 가능하다.

8. Array.prototype.find

9. Array.prototype.findIndex

.find : 콜백함수의 반환값이 true인 첫번째 요소를 반환, true인 요소가 존재하지 않는다면 undefined 반환

.findIndex : 콜백함수의 반환값이 true인 첫번째 요소의 인덱스를 반환, true인 요소가 존재하지 않는다면 -1 반환

var arr = [{name: '소현', age: 10},{name: '나영', age: 8}, {name: '미지', age: 3}];

// 배열의 요소를 반환
console.log(arr.find((item) => item.age < 4)); // {name: '미지', age: 3}

// 배열의 인덱스를 반환
console.log(arr.findIndex((item) => item.age === 8)); // 1
profile
학생 점심 좀 차려

0개의 댓글