Frontend/JS.info 정리

자료구조와 자료형 - 배열과 메서드

Creative_Lee 2022. 2. 8. 11:32

배열에는 다양한 메서드가 있습니다.

 


요소 추가,제거 method

 

splice

arr.splice ( index [ , 삭제를 원하는 요소의 갯수 , 추가할 요소, ...... , 추가할 요소N ] )

 

배열에서 원하는 인덱스로 부터 원하는 요소의 갯수만큼 삭제하고 삭제한 요소로 이루어진 배열을 리턴합니다.

제거와 동시에 해당 공간에 다른 요소를 추가 할 수도 있습니다!

원하는 요소의 갯수를 0으로 입력하면 요소의 제거없이 추가만 할 수 있습니다.

 

let arr = [1 , 2, 3, 4, 5, 6]
let spliceElement = arr.splice(0,3)
console.log(spliceElement) // [1 ,2, 3]

제거한 요소를 배열로 반환하는 splice()
let arr = [1, 2, 3, 4, 5, 6]
let spliceElement = arr.splice(0,3,4,5,6)
console.log(spliceElement) // [1, 2, 3]
console.log(arr) // [4, 5, 6, 4, 5, 6]
삭제 후 요소 추가 가능!

let arr = [1 , 2, 3, 4, 5, 6]
let spliceElement = arr.splice(0,0,4,5,6)
console.log(spliceElement) // []
console.log(arr) // [4, 5, 6, 1, 2, 3, 4, 5, 6]
삭제 없이 요소 추가 가능!

let arr = [1, 2, 3, 4, 5, 6]
let spliceElement = arr.splice(-3,3)
console.log(spliceElement) // [4, 5, 6]
console.log(arr) // [1, 2, 3]
음수 인덱스를 사용하면 배열의 끝부터 계산하여 삭제합니다!

 

 

slice

arr.slice ( [ 시작점 인덱스  , 끝점 인덱스 ] )

 

배열에서 시작점 인덱스부터 끝점 인덱스까지의 요소를 복사해 새로운 배열로 리턴합니다.

끝점은 제외합니다. ( 끝점 전까지 리턴 )

let arr = [1, 2, 3, 4, 5, 6]

let sliceElement = arr.slice(0,3)

console.log(arr) // [1, 2, 3, 4, 5, 6]
console.log(sliceElement) // [1, 2, 3]
인덱스에 해당하는 요소들을 복사하여 배열로 리턴합니다.
let arr = [1 , 2, 3, 4, 5, 6]

let sliceElement = arr.slice(-3)

console.log(arr) // [1, 2, 3, 4, 5, 6]
console.log(sliceElement) // [4, 5, 6]

인자로 음수를 넣으면 배열의 끝부터 계산합니다.
끝점 인자를 넣지 않으면 범위는 배열의 끝까지 입니다.
let arr = [1 , 2, 3, 4, 5, 6]

let sliceElement = arr.slice()
sliceElement.push(7)

console.log(arr) // [1, 2, 3, 4, 5, 6]
console.log(sliceElement) // [1, 2, 3, 4, 5, 6, 7]

인자 없는 호출로 배열복사가 가능합니다!

 

 

concat

arr.concat( 추가할 배열이나 값, 추가할 배열이나 값 ...... ) 

 

기존 배열 arr의 요소와 인자로 받은 배열의 요소, 값을 복사하여 한 곳에 모은 새로운 배열을 리턴합니다.

let arr = [1 , 2, 3, 4, 5, 6]
let arr2 = [7, 8, 9]
let justNumber = 10
let concatArr = arr.concat(arr2,justNumber)

console.log(concatArr) // (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

 

객체가 인자로 넘어오면 (유사배열 포함) 객체의 분해 없이 통으로 복사되어 더해집니다.

let arr = [1 , 2, 3, 4, 5, 6]
let justNumber = {
  0 : 7, 
  length : 1
}
let concatArr = arr.concat(justNumber)

console.log(concatArr) //  [1, 2, 3, 4, 5, 6, {...}]

 

그런데 인자로 받은 유사 배열 객체에 Symbol.isConcatSpreadable 프로퍼티가 true로 존재하면 

concat은 객체를 배열처럼 취급합니다.

따라서 객체를 분해하여 프로퍼티의 값을 복사하여 더합니다.

let arr = [1 , 2, 3, 4, 5, 6]
let justNumber = {
  0 : 7, 
  length : 1,
  [Symbol.isConcatSpreadable] : true
}

let concatArr = arr.concat(justNumber)

console.log(concatArr) //  [1, 2, 3, 4, 5, 6, 7]
특수 프로퍼티가 존재하므로 유사 배열 객체를 배열처럼 취급했습니다.
따라서 기존 배열에 7 요소를 추가했습니다.

 

 

forEach

arr.forEach( function( arr의 각 요소 , index , arr ))

 

배열의 각 요소에 대해 함수를 실행합니다.

let arr = [1, 2, 3]

arr.forEach((item,index,arr) => {
  console.log(`array [${arr}] 에서 index${index}에 해당하는 element는 ${item}입니다.`)
})

array [1,2,3,4,5,6] 에서 index0에 해당하는 element는 1입니다.
array [1,2,3,4,5,6] 에서 index1에 해당하는 element는 2입니다.
array [1,2,3,4,5,6] 에서 index2에 해당하는 element는 3입니다.

 

forEach는 map과 다르게 기존의 array를 변경하고, 문의 밖으로 리턴값을 받지 못합니다.

let arr = [1, 2, 3, 4, 5, 6]

let mulArr = arr.forEach((num,index,arr) => arr[index] = num*3)

console.log(mulArr) // undefined  --> 리턴값이 없습니다 ㅠㅠ
console.log(arr) // [3, 6, 9, 12, 15, 18] --> 원본을 변경했습니다.

 

 


배열 탐색 method

 

indexOf, lastIndeOf, includes

이전 챕터 부분 문자열을 찾는 문자열의 메소드와 문법이 같습니다.

 

arr.indexOf( item , from ) 

배열에서 from인덱스 부터 시작해 왼쪽에서 오른쪽순서로 item을 찾습니다.  

(중복 요소중 가장 처음 요소를 찾고 싶을 때 사용하면 되겠습니다.)

item을 찾으면 인덱스를 리턴하고, 없다면 -1을 리턴합니다.

 

arr.lastIndexOf ( item , from )

배열에서 from인덱스 부터 시작해 오른쪽에서 왼쪽순서로 item을 찾습니다. 

(중복 요소중 가장 마지막 요소를 찾고 싶을 때 사용하면 되겠습니다.)

item을 찾으면 인덱스를 리턴하고, 없다면 -1을 리턴합니다.

 

 

arr.includes( item , from )

배열에서 from인덱스 부터 시작해 item이 있는지 검사합니다.

item을 찾으면 true, 못 찾으면 false를 리턴합니다.

let arr = [1, 1, 2, 2, 3, 3]

console.log(arr.indexOf(3,0)) // 4

console.log(arr.lastIndexOf(3,5)) // 4

console.log(arr.includes(3,0)) // 4

 

includes 메서드는 NaN을 제대로 처리할 수 있습니다.

let arr = [1, 2, NaN]

console.log(arr.indexOf(NaN,0)) // -1
console.log(arr.lastIndexOf(NaN,2)) // -1
console.log(arr.includes(NaN,0)) // true

위 배열탐색 메소드들은 일치 비교 ( === )를 사용합니다
NaN === NaN 의 결과는 false인것 처럼 일치 비교는 NaN에 동작하지 않습니다.

하지만 includes 메소드는 NaN을 정상적으로 처리합니다!

 

 

find, findIndex

객체로 이루어진 배열이 있다고 가정하고 특정 조건에 부합하는 객체를 찾고 싶을 때 find() 를 사용합니다.

 

let result = arr.find ( ( item, index, array ) => { } )

콜백함수의 리턴값이 true일 때 까지 반복하고

true면 해당 요소를 리턴합니다.

조건에 해당하는 요소가 없으면 undefined를 리턴합니다.

 

 

let result = arr.findIndex ( ( item, index, array ) => { } )

find 함수와 동일한 행동을 하고

요소 대신 index를 리턴합니다.

조건에 해당하는 요소가 없으면 -1을 리턴합니다.

let nameArr = [
  {name: 'Lee'},
  {name: 'Kim'},
  {name: 'Park'},
  {name: 'Eun'},
]

console.log(nameArr.find(item => item.name = 'Lee')) // {name: 'Lee'}
console.log(nameArr.findIndex(item => item.name = 'Lee')) // 0

만약 조건에 해당하는 값이 여러 개 라면 제일 먼저 나온 값을 리턴합니다.

보통의 경우에는 콜백함수의 3가지 매개변수중 1번째 item만 사용합니다.

 

 

filter

let results = arr.filter ( ( item, index, array ) => { } )

find 함수와 동일한 행동을 하지만,

여러개의 요소를 전부 찾아 새로운 배열로 리턴합니다.

let nameArr = [
  {name: 'Lee'},
  {name: 'Kim'},
  {name: 'Park'},
  {name: 'Lee'},
]
let filterdByName = nameArr.filter(item => item.name === 'Lee') 

console.log(filterdByName) // [{…}, {…}]
변수에 index 0,3 으로 이루어진 배열이 할당되었습니다.

 

 


배열을 변형하는 메소드

 

map

arr.map((item, index, array) => { })

 

배열의 요소 하나하나에 대해 함수를 호출하고 호출 결과를 새로운 배열로 리턴합니다.

 

let arr = [1, 2, 3, 4, 5, 6]

let mulArr = arr.map(item => item = item*2)

console.log(mulArr) // [2, 4, 6, 8, 10, 12]

 

 

 

sort(fn)

배열의 모든 요소를 문자형으로 변환한 후 유니코드순으로 정렬하여 배열 자체를 변경합니다.

메서드 호출 시 재정렬 된 배열이 리턴되지만

기존 배열도 수정되기 때문에 리턴값은 잘 사용하지 않습니다.

 

let arr = [1, 3, 2, 5, 12, 6]
arr.sort()

console.log(arr) // [1, 12, 2, 3, 5, 6]

요소가 문자열로 취급되어 재 정렬되기 때문에 원하는 결과가 나오지 않습니다.

 

기본 정렬 기준 대신 새로운 정렬 기준이 담긴 함수를 파라미터로 추가할 수 있습니다. 

 

함수는 반드시 값 2개를 비교해야 하고 리턴 값이 있어야 합니다.

 

새로운 정렬 함수의 리턴 값에는 제약이 없습니다.

 

양수를 리턴하면 1번 인자가 2번 인자보다 크다.

음수를 리턴하면 1번 인자가 2번 인자보다 작다.

위 2가지만 나타내면 됩니다.

let arr = [1, 3, 2, 5, 12, 6]

arr.sort((a,b) => a - b);
console.log(arr) // [1, 2, 3, 5, 6, 12]

 

 

reverse

요소를 역순으로 정렬해 줍니다.

재 정렬된 배열을 리턴하지만 기존 배열도 수정되기 때문에 리턴값은 잘 사용하지 않습니다.

let arr = [1, 2, 3, 4, 5, 6]

arr.reverse()

console.log(arr) // [6, 5, 4, 3, 2, 1]

 

 

split

arr.split( '구분자' [ , 제한할 배열 길이] )

 

구분자를 기준으로 문자열을 나누어 배열로 리턴합니다.

2번째 인자로 원하는 배열의 길이를 제한할 수 있습니다. 

구분자를 빈 문자열로 지정하면 글자 단위로 분리됩니다.

let userList = '이도현,진태훈,장재원,김태오'

let user = userList.split(',')
let firstUser = userList.split(',',1)
let splitUser = userList.split('')

console.log(user) // ['이도현', '진태훈', '장재원', '김태오']
console.log(firstUser) // ['이도현']
console.log(splitUser) // ['이', '도', '현', ',', '진', '태', '훈', ',', '장', '재', '원', ',', '김', '태', '오']

 

 

join

arr.join( '배열 요소를 합칠 때 사용할 문자' ) 

 

특정 문자를 사용하여 배열의 모든 요소를 하나의 문자열로 합칩니다.

let userList = ['이도현', '진태훈', '장재원', '김태오']

let joinList = userList.join('......')

console.log(joinList)  // 이도현......진태훈......장재원......김태오

 

 

reduce

arr.reduce( (accumulator , value, index, arr) => { } , [ initial ] )

 

accumulator = 누산값 ( 이전 함수로 계산한 결과 값 )

value = 현재값 ( 배열 순환 중 현재 값 )

initial = 초깃값

 

배열의 각 요소를 대상으로 함수를 적용하고 각 단계의 결과값을 저장하여 누산해서 하나의 최종값을 리턴한다.

let userList = [1, 2, 3, 4]

let reduceList = userList.reduce((total , currentValue) => total + currentValue , 0)

console.log(reduceList)  // 10

initial 값이 없다면 배열의 0번 index값을 초기값으로 사용하고 1번 index부터 함수를 통한 계산을 시작합니다. 

initial 값을 명시하지 않았을 때, 배열이 비어있는 상태라면 에러를 발생시킵니다.

initial 값은 옵션이지만 에러를 방지하기 위해 사용할 것을 권장합니다!

 

 


 

Array.isArray 

값의 배열 여부를 boolean으로 나타냅니다.

let numArr = [1, 2, 3, 4]
let numObj = {num1 : 1, num2 : 2}

console.log(typeof numArr) // object
console.log(typeof numObj) // object
배열은 객체형이기 때문에 typeof 로는 배열인지 정확하게 알 수 없습니다. 

console.log(Array.isArray(numArr)) // true
console.log(Array.isArray(numObj)) // false
Array.isArray를 통해 배열 여부를 확인할 수 있습니다.

 

 

thisArg

함수를 호출하는 대부분의 배열 메서드에서 thisArg를 매개변수 옵션으로 받을 수 있습니다.

 

thisArg는 함수의 this를 나타내고 해당함수의 컨텍스트 정보를 넘겨줍니다.

let graduation = {
  minGrade : 70,
  maxGrade : 100,
  canGraduation(student){
    return student.grade >= this.minGrade && student.grade<= this.maxGrade
  }
}

let studentGradeList = [  
  {grade : 70 },
  {grade : 60 },
  {grade : 90 },
  {grade : 99 }
]

let congratulation = studentGradeList.filter(graduation.canGraduation,graduation)

// let congratulation = studentGradeList.filter(grade => graduation.canGraduation(grade))

console.log(congratulation) // [{…}, {…}, {…}]

 

 

 

 

요약 정리

 

요소 추가,제거

push( item ) - 맨 끝에 요소 추가

pop( ) - 맨 끝의 요소 제거 후 리턴

shift( ) - 맨 앞의 요소 제거 후 리턴

unshift( ) - 맨 앞에 요소 추가

 

splice( pos, deleteCount, items ) - pos부터 delete 카운트 만큼 삭제 후 item 추가

slice ( start, end ) - start부터 end바로 앞 까지 요소를 복사하여 새로운 배열 생성

concat ( items ) - 배열의 모든 요소와 items 를 합쳐 새로운 배열로 리턴

 

 

원하는 요소 찾기

indexOf / lastIndexOf ( item, pos ) - pos부터 시작해 item을 찾고 찾으면 인덱스를, 없다면 -1 리턴

includes( value ) - value가 있으면 true, 없으면 false를 리턴

find/filter (func) - func의 리턴값을 true로 만드는 첫 번째 / 전체 요소를 리턴

findIndex (func) - func의 리턴값을 true로 만드는 첫 번째 요소의 인덱스를 리턴

 

배열 순회

forEach( func ) - 모든 요소에 대해 func를 호출. 리턴은 없음

 

 

배열 변형

map( func ) - 모든 요소에 대해 func를 호출. 리턴값으로 새로운 배열 생성

sort( func ) - func 조건으로 정렬하여 기존 배열 변경. 변경된 배열도 리턴

reverse( ) - 배열의 순서를 뒤집어 기존 배열 변경, 변경된 배열도 리턴

split( value ) - 문자열을 value를 기준으로 요소로 나누어 배열로 리턴

join( value ) - 배열의 요소를 value로 연결하여 문자열로 리턴

reduce( (accumulator , value, index, arr) => { } , [ initial ])

- 요소에 func 호출 --> 리턴값 저장 --> 다음 요소의 func 호출 시 리턴값 전달 --> 반복 후 최종 값 리턴 

 

 

기타

Array.isArray( value ) - value가 배열인지 여부 확인

 

 

 

 

 

기본이 중요하다.