[모던 자바스크립트 Deep Dive] 27장. 배열(2) 배열 메서드

728x90
반응형

* [출처] 이웅모, 모던 자바스크립트 Deep Dive 자바스크립트의 기본 개념과 동작원리(2020) , 위키북스, p.507-528

* 책 읽고 공부한 내용 정리한 TIL 입니다. (정보 전달 목적이 아니라 개인 기록용이니 참고 바랍니다.)


[ctrl + f 로 찾아쓰기]

* Array.isArray > true /false 반환
* Array.prototype.indexOf > 인덱스 반환
* [추가][원본 변경] Array.push (원본 변경 : 원본 배열 반드시 변수에 저장 )
* [삭제][원본 변경] Array.pop   
* [추가][원본 변경] Array.unshift  
* [삭제][원본 변경] Array.shift      
* [추가][원본 변경X] Array.prototype.concat (원본 변경 x : 반환값을 반드시 변수에 할당 )

* [제거][원본 변경] Array.prototype.splice 

* [복사][원본 변경X] Array.prototype.slice 

* [배열>문자열] Array.prototype.join

* [배열 거꾸로][원본 변경] Array.prototype.reverse

* [배열 채우기][원본 변경] Array.prototype.fill ( 특정요소로 채우기, Array.from()과 함께 순차적으로 채우기)

* [배열 검색] Array.prototype.includes

* [배열 평탄화] Array.prototype.flat


27장. 배열 (2) 배열 메서드

27.8 배열 메서드

- 원본 배열( 배열 메서드의 구현체 내부에서 this가 가리키는 객체): 직접 변경하는 메서드 (예_push)

- 원본 배열 직접 변경 x, 새로운 배열 생성해서 반환하는 메서드 (예_concat)

[예제 27-41]

const arr =[1];

//1. push 메서드 : 원본 배열 직접 변경
arr.push(2);
console.log(arr) ; // [1,2]

//가능한 원본 배열 건들지 않는 메서드 사용 추천
//2. concat 메서드 : 새로운 배열 생성하여 반환
const result = arr.concat(3);
console.log(arr);    //[1,2]
console.log(result); //[1,2,3]

 

27.8.1 Array.isArray > true /false 반환

[예제 27-42]
//true
Array.isArray([]);
Array.isArray([1,2]);
Array.isArray(new Array[]);

//false
Array.isArray({});
Array.isArray(null);
Array.isArray(undefined);

 

27.8.3 Array.prototype.indexOf > 인덱스 반환

* 특정 요소 존재 확인시 유용 : indexOf(val) === '-1'  //val이 없을때

                                               : includes(val) 

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

// 중복되는 요소가 있으면 첫 번째 인덱스 반환
arr.indexOf(2); // 1


// 해당 요소가 없으면 -1 
arr.indexOf(4); //-1

// 두번째 인수 : 검색 시작할 인덱스
arr.indexOf(2,2); // 2


//특정요소 존재하는 확인 (1) indexOf (-1)
const word = ['a','b','c']

if(word.indexOf('c' === -1)){ // word 배열에 'c'가 없으면 (-1) 
	word.push('c'); 		  //'c' 추가
}

//특정요소 존재하는 확인 (2) includes 
if (!word.includes('c')){  // word 배열에 'c'가 없으면 
	word.push('c');        //'c' 추가
}

 

27.8.3 push / pop / unshift / shift

[원본 배열 직접 변경] push : 배열 마지막 추가 + 변경된 length 리턴 (이것보다는 스프레드 [...arr,val] 추천)

[원본 배열 직접 변경] pop   : 배열 마지막 삭제 + 제거 요소 반환 (빈 배열 : undefined 반환)

[원본 배열 직접 변경] unshift : 배열 맨 앞 추가 + 변경된 length 리턴 (이것보다는 스프레드 [...arr,val] 추천)

[원본 배열 직접 변경] shift :  배열 맨 앞 삭제 + 제거 요소 반환 (빈 배열 : undefined 반환)

** stack   : push + pop

** queue : push + shift  (( 먼저 넣은것 먼저 꺼냄 )) p.515 참고

** PUSH

[예제 27-46]
const arr = [1,2];

//push : 마지막 요소 추가 + 변경된 length 반환 + 원본 배열 직접 변경
let result = arr.push(3,4);
console.log(result); //4
console.log(arr);    //[1,2,3,4]

[예제 27-52]
//unshift : 맨 앞 요소 추가 + 변경된 length 반환 + 원본 배열 직접 변경
let result = arr.unshift(3,4); 
console.log(result); //4
console.log(arr);    //[3,4,1,2]


[예제 27-47]
위에 코드보다 직접 추가하는게 push메소드보다 속도 빠름
const arr= [1,2];

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


[예제 27-28]
const arr = [1,2];

//ES6 스프레드 문법
const newArr = [...arr,3]; 
console.log(newArr); //[1,2,3];

const newArr2 = [4,...arr];
console.log(newArr2); //[4,1,2];
** POP

const arr = [1,2];
let result = arr.pop(); //2
console.log(result);    //2
console.log(arr)l       //[1]

** 스택(stack)

- pop 메서드 + push메서드 쉽게 구현 가능 (세로)

- 데이터 마지막에 밀어 넣고, 그 데이터 먼저 꺼내기 (후입 선출 :LIFFO)

- 스택은 언제나 가장 마지막에 밀어 넣은 최신 데이터를 먼저 취득

- 데이터 밀어 넣기 (push) + 데이터 꺼내기 (pop)

const Stack = (function(){
	
    function Stack( array = []) {
    	if(!Array.isArray(array)){
			throw new TypeError(`${array} is not an array`); //47장 "에러처리" 참고
        }
	    this.array = array;  
    }
	
    
    Stack.prototype ={
    	constructor: Stack, //19.9.1절 "생성자 함수에 의한 프로토타입 교체" 참고
        push(value){        //스택 가장 마지막에 데이터 넣기
        	return this.array.push(value);
        },
        pop(){              //스택 가장 마지막 데이터, 가
            return this.array.pop(value);
        },
        entries(){          // 스택의 복사본 배열 반환
        	return [...this.array];
        }
    };
    
    return Stack;   
}());

const stack = new Stack([1,2]);
console.log(stack.entries()); //[1,2]

stack.push(3);
console.log(stack.entries()); //[1,2,3]

stack.pop();
console.log(stact.entries()); //[1,2]

27.8.7 Array.prototype.concat

- [원본 배열 변경 x] 배열 마지막 요소로 추가한 새로운 배열 반환

- 전달한 값이 배열이면 배열 해체 & 새로운 배열 요소 추가

[예제 27-57]
const arr1 = [1,2];
const arr2 = [3,4];

//arr1 + arr2 = 새로운 배열 반환
let result = arr1.concat(arr2);
console.lgog(result); //[1,2,3,4]

//맨 뒤에 요소 추가
result = arr1.concat(3);
console.log(result); //[1,2,3];

//arr1 + arr2 + 맨 뒤에 요소 추가
result = arr1.concat(arr2,5);
console.log(result); //[1,2,3,4,5]

//원본 배열은 안 변함
console.log(arr1); //[1,2]


[예제 27-58]
const arr3 =[3,4];

let result = [1,2].concat(arr3); //[1,2,3,4]
let result = result.concat(5,6); //[1,2,3,4,5,6]


[예제 27-59]
//전달한 값이 배열이면 배열 해체 & 새로운 배열 요소 추가
const arr =[3,4]
let result = [1,2].concat([5,6]);
console.log(result); //[1,2,3,4,5,6] 

**unshift & push는 그대로
const arr =[3,4]
arr.unshift([1,2]);
arr.push([5,6]);
console.log(arr); // [ [1,2],3,4,[5,6] ]


[예제 27-60]
//스프레드 문법으로 대체 가능
let result = [1,2].concat([3,4]); //[1,2,3,4]

result = [...[1,2],...[3,4]]; //[1,2,3,4]

 

27.8.8 Array.prototype.splice (시작할 인덱스, 제거할 요소의 개수(옵션), 제거한 위치에 삽입할 요소(옵션))

-[원본 배열 직접 변경] 중간요소 추가 또는 제거

1) 시작할 인덱스 : -1이면 마지막요소를 가리킴 / -n은 마지막에서 n번째 요소

2) 제거할 요소의 개수 (옵션) : 0인경우, 아무런 요소도 제거 안됨

3) 제거한 위치에 삽입할 요소 (옵션)

 

* Splice(1): 인덱스 1부터 모든 요소 제거

* 특정요소 제거 : indexOf + Splice 

[예제 27-61]
const arr= [1,2,3,4];

//인덱스 1부터, 2개요소 제거, 그 자리에 20,30 삽입 
const result = arr.splice(1,2,20,30); 
//제거된 요소 반환
console.log(result); //[2,3] 
console.log(arr);    //[1,20,30,4]


[예제 27-62]
const arr= [1,2,3,4];

//인덱스 1부터, 제거대상 없음, 인덱스 1자리에 100 삽입
const result = arr.splice(1,0,100);
console.log(arr);    //[1,100,2,3,4]
console.log(result); //[] 제거요소는 배열로 반환

[예제 27-63]
const arr= [1,2,3,4];

//인덱스 1부터, 2개요소 제거
const result = arr.splice(1,2);
console.log(arr);    //[1,4]
console.log(result); //[2,3]


[예제 27-64]
const arr= [1,2,3,4];

//인덱스1부터 모든 요소 제거
const result = arr.splice(1);

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


[예제 27-65]
const arr= [1,2,3,1,2];

function remove (array, item) {

	const index = array.indexOf(item); //제거할 item의 인덱스 취득
    
    if (index !== -1) { //제거할 item 요소가 있다면
       array.splice(index,1); // 인덱스 index부터 1개 제거
    }

 return array;
}

console.log(remove(arr,2)); // [1,2,3,1,2]에서 2 찾음 // array.indexOf(2)--> index 1
                            // index 1부터 1개 삭제 -->  [1,3,1,2]
console.log(remove(arr,10)); // [1,3,1,2]



[예제 27-66]
//특정 모든 요소 제거
const arr= [1,2,3,1,2];
function removeAll(array,item) {
	return array.filter(v => v!=item); // 2가 아닌 모든값 나오게 필터
}

console.log(removeAll(arr,2)); //[1,3,1] :

 

27.8.9 Array.prototype.slice(복사 시작 인덱스, 복사 종료 인덱스(생략가능))

- [원본 배열 변경 x] 
1) 복사 시작 인덱스 : 음수는 끝을 의미 slice(-2) = 배열 마지막 두개의 요소 복사 : slice(-1);

2) 복사 종료 인덱스 없으면 [시작인덱스]부터 모두 복사 : slice(1);

3) 인수가 모두 없으면 "얕은복사"로 원본 전체 복사 : slice();

[예제 27-67]
const arr = [1,2,3];

//arr[0] ~ arr[1]까지 (arr[1] 미포함) 복사 반환
arr.slice(0,1); //[1]
arr.slice(1,2); //[2]

//원본 변경 x
console.log(arr); //[1,2,3]


[예제 27-68]
const arr = [1,2,3];

//arr[1]부터 모든 요소 복사 반환
arr.slice(1); // [2,3]


[예제 27-69]
const arr = [1,2,3];

//arr[뒤에서 요소 1개 : 3] 복사 반환
arr.slice(-1); //[3]
arr.slice(-2); //[2,3]


[예제 27-70]
const arr = [1,2,3];

//인수 모두 생략하면 원본 배열 전체 복사 반환 (얕은복사여서 원본과 일치 안함)
arr.slice(); //[1,2,3]

** slice메서드로 복사본 생성 + arguments, HTMLcollection, ModeList 같은 유사 배열 객체 > 배열로 변환 가능

(34장.이터러블 arguments 객체는 유사배열객체 + 이터러블 객체: 스프레드 문법 사용하면 배열로 간단하게 변경)

[예제 27-72]
fucntion sum(){

 var arr = Array.prototype.slice.call(arguments);
 console.log(arr); // [1,2,3]
    
 return arr.reduce(function (pre,cur){
    	return pre+cur;
    },0);
 }

console.log(sum(1,2,3)); //6

[예제 27-73]
function sum() {
	const arr = Array.from(arguments);
    console.log(arr); //[1,2,3]
    
    return arr.reduce((pre,cur) => pre +cur,0);
}

console.log(sum(1,2,3)); //6

[예제 27-74]
function sum() {
	const arr = [...arguments];
    console.log(arr); //[1,2,3]
    
    return arr.reduce((pre,cur) => pre +cur,0);

}
console.log(sum(1,2,3)); //6

27.8.10 Array.prototype.join

-  배열 > 문자열로 변환 

[예제 27-75]
const arr = [1,2,3,4];

//기본 구분자 : 콤마
arr.join(); //'1,2,3,4'

//배열>문자열 +모두 연결
arr.join(''); //'1234'

//배열>문자열 +
arr.join(':'); //'1:2:3:4'

 

27.8.11 Array.prototype.reverse

-[원본 배열 변경] 배열 순서 반대로

[예제 27-76]
const arr = [1,2,3];
const result = arr.reverse(); 

console.log(arr);    //[3,2,1]
console.log(result); //[3,2,1]

27.8.12 Array.prototype.fill

-[원본 배열 변경] 배열 요소 채우기

[예제27-77]
//0으로 배열 처음부터 끝까지 채움
const arr =[1,2,3];
arr.fill(0);
console.log(arr); //[0,0,0]

[예제27-78]
//0으로, 인덱스1부터 끝가지 채움
const arr =[1,2,3];
arr.fill(0,1); 
console.log(arr); //[1,0,0]

[예제27-79]
//0으로, 인덱스1부터 3까지(인덱스 3 미포함) 끝가지 채움
const arr =[1,2,3,4,5];
arr.fill(0,1,3);  
console.log(arr); //[1,0,0,4,5]


[예제27-80]
//특정요소값(1)로 채우기 가능
const arr = new Array(3); //[empty,empty,empty]

const result = arr.fill(1); 
console.log(result); //[1,1,1]
console.log(arr); //[1,1,1]

[예제27-80]
//순차적으로 채우기 가능 (*Array.from 메서드 )
const seq = (length = 0) => Array.from({length}, (_,i)=>i);
console.log(seq(3)); //[0,1,2]

** 순차적으로 채우기 가능 (*Array.from 메서드 )

Array.from( {length}, ~~) = Array.from ( new Array(length), ~~)

 

27.8.12 Array.prototype.includes

- 특정요소 포함되어 있는지 확인 / true false 반환 / 첫번째 인수로 검색 대상 지정

[예제 27-82]
const arr = [1,2,3]

//값 2가 있는지 확인
arr.includes(2); //true
arr.includes(100); //false


[예제 27-83]
const arr = [1,2,3]

//값 1이 있는지, 인덱스 1부터 확인
arr.includes(1,1); //false
//값 3이 있는지, (음수): length프로퍼티 + (음수) ==> 3-1 =2 : 인덱스 2부터 확인
arr.includes(3,-1); //true

 

27.8.13 Array.prototype.flat

- 재귀적으로 배열 평탄화

[예제 27-85]
[1,[2,3,4,5]].flat(); //[1,2,3,4,5]


[예제 27-86]
//중첩 배열 평탄화: 깊이의 기본값 = 1
[1,[2,[3,[4,]]]].flat();  //[1,2[3,[4]]]
[1,[2,[3,[4,]]]].flat(1); //[1,2[3,[4]]]

//동일
[1,[2,[3,[4,]]]].flat(2); //[1,2,3,[4]]
[1,[2,[3,[4,]]]].flat().flat(); //[1,2,3,[4]]

//모든 중첩 배열 평탄화:infinity 
[1,[2,[3,[4,]]]].flat(infinity); //[1,2,3,4]
반응형