Javascript ES6 - Array

김찬영·2020년 11월 20일
2

ES6 문법

목록 보기
2/4
post-thumbnail

구현하는 기능과 배우는 컨셉

push/unshift
splice
slice
pop / shift /
concat /
forEach
map
filter
reduce

👉push/unshift

let cities = [];
cities.push("경주", "전주");
cities.unshift("인천");

push 결과 값:["경주", "전주"]
unshift 결과 값 : ["인천", "경주", "전주"]

◾ push(), unshift() 함수는 요소를 추가해주는 함수
◾ push는 array의 마지막 부분, 즉 꼬리에 요소들을 추가
◾ unshift는 array의 맨 앞부분, 즉 머리 부분에 요소를 추가


👉 pop

let arr = ['A', 'B', 'C', 'D', 'E'];
arr.pop()

arr.pop() 리턴 값 : 'E'
arr의 현재 결과 값 : ["A", "B", "C", "D"]

arr.pop();

arr.pop() 리턴 값 : 'D'
arr의 현재 결과 값 : ["A", "B", "C"]

◾ pop() 메소드는 배열의 가장 뒤 element를 삭제하고, 삭제한 element를 리턴한다.
◾ 배열 인덱스 뒤에부터 삭제가된다.
◾ 파라미터가 없다
◾ 리턴값 : 삭제한 element


👉 shift

let arr = ['A', 'B', 'C', 'D', 'E'];
arr.shift()

arr.pop() 리턴 값 : 'A'
arr의 현재 결과 값 : ["B", "C", "D"]

arr.shift()
arr.pop() 리턴 값 : 'B'
arr의 현재 결과 값 : ["C", "D"]

◾ shift() 메소드는 배열의 가장 앞 element를 삭제하고, 삭제한 element를 리턴한다.
◾ 배열 인덱스 앞에서부터 삭제가된다.

👉 slice

slice(start, end)
start :

  • undefined인 경우 : 0부터 slice
  • 음수 : 배열의 끝에서부터의 길이를 나타냄 -2이라면 배열의 마지막 2개의 요소를 추출한다.
  • 배열의 길이와 같거나 큰 수를 지정한 경우 빈 배열을 반환한다.

end : 추출을 종료할 기준 index (end를 제외하고 그 전까지의 요소만 추출한다.)
◾ 배열의 길이와 같거나 큰 수를 지정한 경우 배열의 끝까지 추출한다.
◾ 반환값: 추추한 요소를 포함한 새로운 배열

function sliceCityFromAddress(address) {
  
  let siIndex = address.indexOf('시');
  let doIndex = address.indexOf('도');
  if (doIndex !== -1) {
    
    address = address.slice(0, doIndex+1)+address.slice(doIndex+5, address.length)
  
  }else if(siIndex !== -1){
  
    address = address.slice(siIndex+2, siIndex.length)
    
  }
  
  return address
}
sliceCityFromAddress('경기도 성남시 중앙공원로 53')
sliceCityFromAddress('서울특별시 강남구 테헤란로 427 위워크타워')
sliceCityFromAddress('경기도 성남시 분당구 판교역로 235')

결과 값 :
'경기도 중앙공원로 53'
'강남구 테헤란로 427 위워크타워'
'경기도 분당구 판교역로 235'

sliceCityFromAddress에서 호출한 문자열중에서 '도'가 있을경우 '~시' 를 빼고 출력하고싶을 때

◾ indexOf를 통해 '도'가 address값에 있다면 slice(0, doIndex+1) + slice(doIndex+5, address.length)를 통해 ~도를 뺀다
◾ 좀더 설명해보저면, 0부터 3인 '경기도' + 7부터 끝까지 '중앙~53'을 더한다
◾ '경기도' +'중앙공원로 53'이 더해져서 '경기도 중앙공원로 53'이된다.
◾ 여기서 주의할점은 address.length는 16인데 index는 0부터 시작하므로 15가 되어야하는게 아닌가? 생각했는데 slice ( start , end)의 end 특징요소가 자기자신은 포함하지않기 때문에 마지막도 출력하게하려면 index +1를 해줘야한다. 근데 length자체가 index+1이므로 length를 써도 무방하다.

👉splice

◾ splice를 이용하면 원하는 위치에 요소를 추가하거나 삭제할 수 있습니다
splice ( start index, deleteCount , itme1, itme2..)
start index : 배열 변경을 시작할 index

  • 음수를 지정한 경우 배열의 끝에서부터 요소를 센다
  • 배열의 길이보다 큰 수를 지정한 경우: 실제 시작 인덱스는 배열의 길이로 설정됨
  • 절대값이 배열의 길이보다 큰 경우 0으로 세팅

◾ deleteCount : 배열에서 제거할 요소의 수

  • 생략값이 배열의길이가 start보다 큰경우는 start부터 모든 요소를 제거한다
  • 0 이하의 수를 지정하면 어떤 요소도 제거되지 않는다.
    ◾ item1 ... : 배열에 추가할 요소
  • 지정하지 않는 경우 splice()는 요소 제거만 수행한다
    ◾ 반환값 : 제거한 요소를 담은 배열
[ 추가 ]
<1>
let arr = ['A', 'B', 'C', 'D', 'E'];

arr.splice (2,0, "7");

결과 값 : ["A", "B", "7", "C", "D", "E"]

<2>
let arr = ['A', 'B', 'C', 'D', 'E'];

arr.splice(5, 0, "7");

결과 값 :["A", "B", "C", "D", "E", "7"]

◾ start 요소를 지정하지 않으면 splice()는 배열의 요소만 제거한다
◾ <1>를 보면 index 2번째인 'C'자리에 item '7'를 추가한다
◾ <2>를 보면 index가 없는상태도 새로 추가 생성이 가능하다

[ 제거 ]
<1>
let arr = ['A', 'B', 'C', 'D', 'E'];

arr.splice(2, 1);

결과 값 : ["A", "B", "D", "E"];


◾ <1>를 보면 index 2번재인 'C'자리에 인덱스 하나를 제거함을 나타냅니다.
◾ 제거할시에는 item을 사용하지않는 것이 차이점이라고 볼 수있습니다.


👉 concat

let arrB = ['A', 'B', 'C', 'D', 'E'];
let arrA = ['a', 'b']
let newArr = arrB.concat(arrA);

결과 값 : 
[
  'a', 'b', 'A',
  'B', 'C', 'D',
  'E'
]

◾ 추가하고싶은 arr.concat(추가하고싶은 arr)
◾ 순서는 앞에 먼저쓴 arr순으로 나타난다.
◾ 새로운 배열을 반환한다

👉

let arr = ['A', 'B', C', 'D']

console.log(arr.includes('A'))
console.log(arr.includes('F'))

결과 값 : 
true
false

👉 forEach vs map

forEach

◾ forEach()은 배열을 순회하면서 배열의 각 원소들을 출력합니다.
◾ forEach는 return이 없습니다. 즉, callback 함수에 의해서 어떤 결과물을 내놓고 싶으면 함수 밖의 변수를 사용해야합니다.
◾ forEach는 아무것도 리턴하지않는다 (undefined). 단지 제공된 함수로 Array 요소를 호출합니다. 호출하는 Array를 변경할 수 있습니다

map

◾ map()은 모든 Array 요소가 제공된 함수로 호출될때 새로운 array를 생성합니다
◾ map 메소드는 Array안에 요소들을 호출한다.
◾ forEach()와 다른점은 값을 사용하고 Array와 동일한 사이즈의 새로운Array을 반환한다

Array에서 만약 각 요소를 2배로 올리고싶다면 map과 forEach 무엇을 사용할까?

<forEach>
arr.forEach((num, index) => {
  return (arr[index] = num * 2);
});

// 결과
// arr = [2, 4, 6, 8, 10]

<map>
let double = arr.map(num => {
  return num * 2;
});

// 결과
// doubled = [2, 4, 6, 8, 10]

속도 측정

◾ forEach()가 map()보다 70% 속도가 느리다. (브라우저마다 약간 다름)
◾ 함수형 프로그램을 선호한다면 map()을 사용하는 것이 더 바람직하다
◾ forEach() 기존의 Array를 변경하기 때문인데, 반면 map()은 새로운 Array를 반환한다.
◾ 그러므로 기존의 배열을 변경하지않는다!!

무엇이 더 좋을까요?

◾ 상황에 따라 달라진다.
◾ forEach()는 Array안에 데이터를 변경하려는 것이 아니라 데이터베이스에 저장하거나 로그아웃하는것과 같은 작업에 유용할 수 있다.
◾ map()은 데이터를 변경할때 선호 될 수 있다. 더 빠를뿐아니라 새로운 배열을 반환한다.
다른 메소드들과 함께 사용할 수 있다. (map / filter / reeduce등)

let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);

// arr2 = [6, 8, 10]
let arr = [1, 2, 3, 4, 5];
let arr2 = arr.map(num => num * 2).filter(num => num > 5);

// arr2 = [6, 8, 10]

map 사용법

arry.map(callbackFunction(currentValue, index, array), thisArr)

◾ filter, forEach와 같은 구문이다.
◾ callbackFunction, thisArry 두개의 매개변수가 있고, callbackFunction은currentVaule, index, array 3개의 매개변수를 갖는다.

  • currentValue : 배열 내 현재 값
  • index : 배열 내 현재 값의 인덱스
  • array : 현재 배열
  • thisArg : callbackFunction 내에서 this로 사용될 값

map 함수연습

let brands = [
{id:1, name ="NIKE"},
{id:2, name ="ADD"},
{id:3, name ="BANANA"},
{id:4, name ="OR"},
]

이러한 Object(객체)타입의 변수가 있다.
여기서 이름만 추출하고 싶다면?


let names = brands.map(brand => brand.name);
console.log(names)
결과 값 : [ 'NIKE', 'ADD', 'BANANA', 'OR' ]

let infoTeamOne = 
    [
      {name : "김찬영", salary : 5000000},
     {name : "박민철", salary : 1000000},
     {name : "이두형", salary : 3000000},
     {name : "최두림", salary : 4000000}];
 
 let newJson = infoTeamOne.map((element, index,a)=>{   
       let returnObj = {}
        returnObj[element.name] = element.salary;
        return returnObj;
    });
    console.log(newJson)
   결과 값 : [
  { '김찬영': 5000000 },
  { '박민철': 1000000 },
  { '이두형': 3000000 },
  { '최두림': 4000000 }
]

◾ 배열안에 객체를 만들고 각각 차례대로 보관한다.
◾ map함수를 이용해서 returnObj라는 새로운 객체에 key, value를 넣고 배열을 만든다.


👉reduce

const numbers = [1, 2, 3, 4, 5];

const avg = numbers.reduce((accumulator, current, index, array) => {
if (index === array.length - 1){
  return (accumulator + current) / array.length;
  }
  return accumulator + current
  }, 0);
  console.log(avg);
  
 결과 값 : 3
  

◾ recuce는 인자값으로 accumulatr, current, index, array라는 콜백함수와 accumulator초기화 값을 지정해주는 콜백함수로 총 2개의 콜백함수로 구성되어있다.
◾ accumulator값은 누적된 값을 의미한다
◾ current는 배열의 각각의 원소들을 가리킨다
◾ 위의 코드는 배열의 평균값을 구하는 코드인데, 보통 reduce는 배열의 계산에 유용하다.
◾ 두번쨰 콜백함수 인자는 accumulator의 처음 초기화로 설정된다.

accumulator = 0일때, current는 1이므로 accumulator는 1이되고,
accumulator = 1일때, current는 2이므로 accumulator는 3이되고
a-ccumulator = 3일때, current는 3이므로 accumulator는 6이되고
accumulator = 6일때, current는 4이므로 accumulator는 10이되고
accumulator = 10일때, current는 5이므로 accumulator는 15이된다
그리고 index는 5일때, 배열의 길이 -1은 index의 마지막이므로 if문 조건에 성립이된다.
그래서 index가 5일때, 15 / 5 가되어 3을 return하게 된다.

배열에서 각각의 알파벳 갯수 알아내기

const alphabets = ['a','b','c','a','b','c',];
const count = alphabets.reduce((acc, current) => { 
   if(acc[current]) {
    acc[current] += 1;
    } else {
    acc[current] = 1;
    }
    return acc;
    }, {}}
    
    console.log(count)
    
    결과 값 : { a: 2, b: 2, c: 2 }

acc의 초기값을 빈 객체로 설정하면 빈객체안에 값이 count로 출력된다.
acc가 빈객체일때, current는 'a'이므로 acc['a'] = 1이 실행되어 { a : 1} 이 되고,
acc가 { a : 1 }일때, currents는 'b'이므로 acc['b'] = 1이 실행되어 { a: 1, b:1}이 되고 acc가 { a: 1, b:1}일때, current는 'c'이므로 'acc['c'] = 1이 실행되어 { a :1, b : 1, c :1 }` 이된다
이를 계속하면 최종적으로 결과값이 나오게된다.
참고로, if문 조건을 해석하자면 acc 초기값이 빈객체이므로 current에 값이 있으면 객체에 추가되며,
acc[current]는 acc['a'] 랑 같은 거기때문에, 만약 acc['a']가 있다면 +=1이되어 계속 value값이 추가된다.

profile
Front-end Developer

0개의 댓글