[JavaScript] 배열

aseol·2023년 10월 29일
0

JavaScript

목록 보기
11/15

배열

배열이란? 숫자가 있는 리스트라고 볼 수 있는데, 여러 개의 데이터를 하나의 저장소에 저장하려 할 때 유용하다. 배열에 담긴 대상을 값·요소라고 하는데, 문자뿐만 아니라 숫자 · 객체 · 함수 등도 포함할 수 있다.

각각의 데이터는 배열로 나누어진 저장소에 나열되며, 각각의 저장소에는 인덱스 번호(번지수)가 부여된다. 인덱스 번호는 0부터 시작한다.

배열 객체에 저장된 데이터 불러오기 🔽

참조변수 [ 인덱스 번호 ]

let array = ['철수', '영희', '맹구'];

console.log(array[0]); // 철수
console.log(array[1]); // 영희

수정도 가능하다

array[0] = '짱구'; 

console.log(array[0]); // 짱구
console.log(array[1]); // 영희

🔷 생성자

Array()는 new를 붙이거나 붙이지 않고 호출할 수 있다.
둘 다 새 Array 인스턴스를 생성한다.

  • 참조변수 = [] ;
  • 참조변수 = new Array() ;
    • 매개변수 1개일 경우
      ① 숫자 → 배열의 길이
      ② 문자열 → 배열의 요소
    • 매개변수 2개 이상일 경우
      문자열 → 배열의 요소
    let test = new Array(3);
    console.log(test.length);
    
    let test2 = new Array('김', '이', '박');
    console.log(test2);

🔷 속성

Array: length

  • Array 인스턴스의 length 속성은 배열의 길이를 반환한다.
    ➡️ 배열의 최대 인덱스보다 항상 크다.
    ( 배열의 길이 - 1 = 배열의 마지막 요소의 인덱스 )

  • length 속성에 값을 설정할 경우 배열의 길이를 변경한다.
단일 숫자 매개변수가 있는 생성자를 사용하여 배열을 만들 수 있는데, 
length 속성이 해당 숫자로 설정되어 생성되며, 배열 요소는 빈 슬롯이다.

배열의 길이를 5로 설정하고 출력해 보니 실제 원소 수가 증가하였고, 
추가된 2개의 요소는 undefined인 것으로 출력된다.

🔷 메소드

👍 비순수함수 계열

함수 내부에서 외부 상태를 변경하거나, 입출력 외에 다른 데이터에 영향을 주는 경우
➡ 같은 입력에 대해 항상 같은 출력을 보장하지 않으며, 동작이 예측 가능하지 않을 수 있다.

◽ isArray()

Array.isArray() : 전달된 인수가 배열이면 true, 배열이 아니면 false 를 반환

// true
  Array.isArray([]);
  Array.isArray([1]);  
  Array.isArray(new Array());
  // false  
  Array.isArray();
  Array.isArray({});
  Array.isArray(null);
  Array.isArray(undefined);

◽ indexOf / lastIndexOf / includes()

Array.prototype.indexOf(찾을 요소[, 검색을 시작할 인덱스]) : 배열에서 지정된 요소를 찾을 수 있는 첫 번째 인덱스를 반환하고, 존재하지 않으면 -1을 반환
Array.prototype.lastIndexOf(찾을 요소[, 검색을 시작할 인덱스]) : 배열에서 역순으로 검색하여 주어진 값과 일치하는 마지막 요소의 인덱스를 반환하고 , 존재하지 않으면 -1을 반환

검색을 시작할 인덱스(fromIndex)를 지정하지 않은 경우에는 전체 배열을 검색

Array.prototype.includes(찾으려는 요소) : 해당 배열의 요소 있으면 true, 없으면 false 반환

const arr = [1, 2, 2, 3];
console.log(arr.indexOf(2)); // 1
console.log(arr.indexOf(3)); // 3 
//두 번째 인수는 검색을 시작할 인덱스
console.log(arr.indexOf(3, 2)); // 3
console.log(arr.indexOf(4, 2)); // -1 
let isIncludes = arr.includes(4);
console.log(isIncludes); // false

◽ unshift / shift / push / pop()

Array.prototype.unshift() : 인수로 전달받은 모든 값을 원본 배열의 선두에 추가하고 length 프로퍼티 값을 반환
Array.prototype.shift() : 원본 배열에서 첫번째 요소를 제거하고 제거한 요소를 반환

const arr3 = [100, 200, 300, 400];
let shiftLength = arr3.unshift(1,2);
console.log(shiftLength); // 6
console.log(arr3); // (6) [1, 2, 100, 200, 300, 400]
let shiftValue = arr3.shift();
console.log(shiftValue); // 1

Array.prototype.push() : 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length 프로퍼티 값을 반환
Array.prototype.pop() : 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환

const arr2 = [1, 2, 3, 4];
let returnLength = arr2.push(5,6); 
console.log(returnLength); // 6 
let popValue = arr2.pop(); //  메소드 호출 후 제거된 마지막 요소 반환
console.log(popValue); // 6


💡 unshift / shift are slower than push / pop.
뒤에서부터 넣고 빼는 것은 빈 공간에 데이터를 넣었다 지웠다 하는 것이므로 (한 공간에 인덱스를 이용해 넣고 빼고 하므로) 기존에 들어 있던 데이터들은 움직이지 않아도 된다
➡️ fast operation
그러나 앞에서부터 데이터를 넣으려면 기존에 앞에 있던 데이터를 그다음 칸으로 넣어 앞을 비운 다음 넣어야 한다. 데이터를 뺄 때도 마찬가지로, 첫 번째 아이템을 지우면 두 번째에 있던 아이템은 앞으로 당겨 오고 세 번째 아이템을 두 번째로 당겨오고 하는 식의 과정을 반복하므로 기존에 들어 있던 데이터들이 움직여야 한다
➡️ slow operation (이는 배열의 길이가 길수록 심해진다)

◽ splice()

Array.prototype.splice(시작할 인덱스[, 제거할 요소수, 추가할 요소 ···]]) : 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경하며, 제거한 요소를 반환

추가할 요소를 작성하지 않은 경우 요소를 제거하기만 한다.
const arr3 = [2, 100, 200, 300, 400];
const arr4 = [10, 20, 30, 40];
let resultSplice = arr4.splice(2, 1, 300, 400); 
console.log(arr4); // (5) [10, 20, 300, 400, 40]
console.log(resultSplice); // [30] : 제거한 요소가 담긴 배열 
let resultSplice2 = arr4.splice(2, 1, ...arr3); 
console.log(arr4); // (9) [10, 20, 2, 100, 200, 300, 400, 400, 40]
console.log(resultSplice2); // [300] : 제거한 요소가 담긴 배열 

✌️ 순수함수 계열

함수가 외부의 상태를 변경하지 않고, 입출력 외에는 다른 데이터에 영향을 주지 않는다.
➡ 동일한 입력에 대해 항상 같은 출력을 생성하므로, 프로그램의 예측 가능성을 높여준다.

◽ slice()

Array.prototype.slice(복사를 시작할 인덱스, 복사 종료할 인덱스) : 인수로 전달된 범위의 요소들을 복사하여 배열로 반환

const arr5 = [100,200,300,[3,4],400];
let resultSlice = arr5.slice(1,2);
// 인수가 없을 시 새로운 배열을 반환하여 요소 복사
const shallowArr = arr5.slice();
console.log(arr5); // (5) [100, 200, 300, Array(2), 400]
console.log(resultSlice); // [200]
// 복사하는 요소가 객체타입일 경우 얕은 복사
console.log(shallowArr); // (5) [100, 200, 300, Array(2), 400]
console.log(arr5[3] == shallowArr[3]); // true

◽ concat()

Array.prototype.concat() : 두 개 이상의 배열을 병합하는 데 사용 (기존 배열을 변경하지 않고 새 배열을 반환)

		const targetArr1 = [1,2];
		const targetArr2 = [3,4];
		const concatArr = targetArr1.concat(targetArr2);
		console.log(targetArr1);
		console.log(targetArr2);
		console.log(concatArr);

◽ flat()

Array.prototype.flat([depth]) : 모든 하위 배열 요소를 지정한 깊이까지 재귀적으로 이어붙인 새로운 배열을 생성하여 반환 / 배열의 구멍 제거

배열의 깊이(depth)를 작성하지 않으면 기본값인 1이 적용된다 
const arr6 = [1,2,[3,4,[5,6,[7]]],8,9];
const flatArr = arr6.flat(Infinity);
console.log(arr6); // (5) [1, 2, Array(3), 8, 9]
console.log(flatArr); // (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]

◽ reverse()

Array.prototype.reverse() : 메서드는 배열의 순서를 반전 ➡ 첫 번째 요소는 마지막 요소가 되며 마지막 요소는 첫 번째 요소가 된다.

const arr6 = [1,2,[3,4,[5,6,[7]]],8,9];
const flatArr = arr6.flat(Infinity);
console.log(arr6);
console.log(flatArr);
const reverseArr = flatArr.reverse();
console.log(flatArr);
console.log(reverseArr);

◽ forEach()

Array.prototype.forEach(callback(currentvalue[, index[, array]])[, thisArg]) : 주어진 함수를 배열 요소 각각에 대해 실행

callback은 3개의 인수를 받아 호출될 수 있다 🔽

1. currentvalue : 처리할 현재 요소
2. index : 처리할 현재 요소의 인덱스
3. array : forEach()를 호출한 배열 (순회 중인 배열)

thisArg : callback을 실행할 때 this로 사용할 값

◽ some( )

배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 테스트하여
만약 배열에서 주어진 함수가 true을 반환하면 true를 반환하고, 그렇지 않으면 false를 반환

const testArray = [1,2,3,4,5,10];

// 배열 안에 2의 배수가 있는지 
const even = (element) => element % 2 == 0
const result1 = testArray.some(even);
console.log('2의 배수가 존재할까? ',result1);

// 배열 안에 5의 배수가 있는지
const result2 = testArray.some(function(element){
	return (element % 5 == 0);
})
console.log('5의 배수가 존재할까?',result2);

업로드중..

👌 고차함수 계열

◽ sort()

Array.prototype.sort([compareFunction]) : 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환 / (배열 자체가 변경된다)

정렬 순서를 정의하는 함수(compareFunction)가 제공되지 않으면 
요소를 문자열로 변환하고 유니 코드 코드 포인트 순서로 문자열을 비교하여 정렬된다. 
 (예를 들어 "바나나"는 "체리"앞에 온다 /  
 숫자 정렬에서는 9가 80보다 앞에 오지만 숫자는 문자열로 변환되기 때문에 "80"은 유니 코드 순서에서 "9"앞에 온다.)

💡 a와 b를 비교하여

  • a가 작으면 ( a - b < 0 ) ➡ a가 앞으로 온다.
  • 동일하면 ( a - b = 0 ) ➡ 서로에 대해 변경하지 않는다.
  • a가 크면 ( a - b > 0 ) ➡ b가 앞으로 온다.

◽ map()✅

Array.prototype.map(value) : 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환

const array1 = [1, 4, 9, 16];
// Pass a function to map
const map1 = array1.map((x) => x * 2);
console.log(map1);
// Expected output: Array [2, 8, 18, 32]
const targetArr3 = [1, 2, 3, 4];
const mapArr = targetArr3.map((v, i, arr) => {
	console.log(`element : ${v} || index : ${i} || this : ${arr}`);
	return v + 1;
		})
console.log(mapArr); // (4) [2, 3, 4, 5]

const mapArr2 = targetArr3.map(v => v + 1);
console.log(mapArr2); // (4) [2, 3, 4, 5]
console.log(targetArr3); // (4) [1, 2, 3, 4] // 기존 배열에는 영향이 없음 

∴ 아무런 반환값을 갖지 않는 함수가 주어졌을 경우 콜백함수는 아무런 값을 반환하지 않아 배열의 각 요소는 undefined가 된다.

주어진 콜백 함수는 아무런 값을 반환하지 않고, 대신 console.log('print') 문장을 실행
➡ 이러한 경우 forEach() 메소드를 사용하는 것이 낫다.

◽ filter()

Array.prototype.filter(callback) : 각 요소를 시험할 함수를 전달하면 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환

◽ join()

Array.prototype.join() : 배열의 모든 요소를 연결해 하나의 문자열로 만든다.

◽ reduce()

Array.prototype.reduce(callback[, initialValue]) : 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환

acc : 누산기(accumulator). 누적 계산값 (콜백의 반환값을 누적) 
💥 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출
💥 initialValue를 제공한 경우에는 initialValue의 값
cur : 현재 값 (currentValue)

(Optional) 🔽
currentIndex : 현재 인덱스 (지금이 몇 번째 인덱스인지)
array : 원본 배열 
initialValue : callback의 최초 호출에서 첫 번째 인수에 제공하는 값. 
초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용 (빈 배열에서 초기값 없이 reduce()를 호출하면 오류가 발생)

2의 배수만 배열에 들어가도록 하기

반복문

for

for ··· of 보다 길게 작성해야 하지만 index도 얻을 수 있다.

for ··· of

배열도 객체이기 때문에 for in(➡️ 객체를 순회)을 사용할 수 있지만 장점보다 단점이 많기 때문에 for of를 사용하도록 하자.


참조
https://www.javascripttutorial.net/javascript-array-indexof/

0개의 댓글