[배열이란]
- 보통 배열을 사용하는 용도는 묶음 단위로 데이터를 구분할 때 사용함
- 기본적인 자료구조
[자바스크립트 배열]
- 자바스크립트 배열은 객체 : 내장 객체(미리 만들어져있고, 사용하면 되는 객체)
- 객체지만 내부적으로 배열로서 특화된 객체 : 배열 관련 프로퍼티
- 자바스크립트 배열은 한 배열 내 다양한 타입의 요소를 포함시킬 수 있음 : 스크립트 언어가 대부분 그럼
- 배열은 레퍼런스 타입
[자바스크립트 배열 생성 방법]
1) [ ]를 이용한 배열 선언
1 2 3 4 5 6 | var numbers = []; /* for문을 통해 numbers 배열에 요소 추가 */ for(var i = 0; i < 10; i++){ numbers[i] = i+1; } | cs |
2) Array 생성자 호출1 - 배열 요소 전달
1 2 3 4 5 | var numbers = new Array(); // [ ] /* or */ var numbers = new Array(1,2,3,4,5); // === [1,2,3,4,5] | cs |
3) Array 생성자 호출2 - 배열 길이 전달
1 2 | var numbers = new Array(10); console.log(numbers.length); // 10 | cs |
- 인수 갯수에 따라 요소를 전달할 것(0개 or 2개 이상)인지 길이를 전달할 것(1개)인지 정해짐
[자바스크립트 배열 프로퍼티]
- 다시 말하지만 자바스크립트 배열은 (특화된)객체 : 배열 관련 메서드를 상속받고(프로토타입체인), length 내장 프로퍼티가 있음
1 | console.log(numbers.length); | cs |
- 아래 이미지는 배열의 __proto__ 프로퍼티 내부를 본 것 : Array prototype
[자바스크립트 배열 및 Array 메서드 활용하기]
- 아래 기능 중 브라우저의 자바스크립트 엔진에 따라 지원하지 않을 수 있음
- 지원하지않는다면 지원하는 브라우저로 테스트한 후 지원하지않는 브라우저에서는 어떻게 구현하는지 찾아보기
(MDN, Array.prototype 객체 메서드 문서를 보면 폴리필이라는 제목 아래에 그 방법이 나와있음)
1) 문자열을 쪼개 배열 만들고 출력하기 : String.prototype.split return array
1 2 3 4 5 | var sentence = "안녕 나는 박진형이라고 해"; var words = sentence.split(" "); for(var i = 0; i<words.length; i++) console.log(words[i]); | cs |
2) A배열과 쌍둥이 B배열 만들기 : 레퍼런스 타입이라 같은 메모리 주소값(배열 객체를 저장)을 저장하게함
1 2 3 4 5 6 7 | var arr1 = []; for(var i=0; i<10; i++){ arr1[i] = i + 1; } var arr2 = arr1; console.log(arr1 === arr2); // true | cs |
- arr1의 배열요소가 변경되면 arr2도 변경 : 하나의 메모리 주소값에 있는 배열이 변경되는 것
- 이를 얕은 복사라 함
3) A배열 요소 내용만 복사하기 : 같은 메모리 주소값을 저장하는 것이 아니라 요소만 단순히 옮기는 것
1 2 3 4 5 6 7 8 9 10 11 12 13 | var arr1 = [1,2,3,4,5]; function copy(arr){ var result = []; for(var i=0; i<arr.length; i++) result[i] = arr[i]; return result; } var arr2 = copy(arr1); console.log(arr1 === arr2); // false | cs |
- 1차원 배열일 때를 가정해두고 만든 함수임
- 이를 깊은 복사라 함
4) 배열의 요소로 존재하는지 알기 : Array.prototype.indexOf
1 2 3 4 | var arr = [1,2,3,4,5,1]; arr.indexOf(6); // -1 arr.indexOf(1); // 0 : 배열에서 0번째에 가장 먼저 위치 arr.lastIndexOf(1); // 5 | cs |
- 존재할 때 배열의 요소 인덱스 값 리턴
- 존재하는데, 여러개가 존재할 대 가장 첫번째 값의 위치(인덱스)를 리턴
- 존재하지않을 때 -1 리턴
- lastIndexOf : indexOf와는 일부 반대개념, 존재할 때 가장 뒤의 위치를 리턴해줌
5) 배열 요소를 하나로 합쳐 문자열로 만들기 : Array.prototype.join
1 2 3 4 | var arr = ["안녕하세요", "저는", "박진형입니다."]; var str = arr.join(); console.log(str); // "안녕하세요,저는,박진형입니다." | cs |
- 문자열로 만들어주긴하나, ,(콤마)로 요소들을 구분한 상태에서 문자열로 만듬
6) C배열 = A배열 + B배열 : Array.prototype.concat
1 2 3 4 | var arr1 = [1,2,3,4,5]; var arr2 = [6,7,8,9,10]; var arr3 = arr1.concat(arr2); // [1,2,3,4,5,6,7,8,9,10] | cs |
- 두 배열의 요소를 합쳐 새로운 배열 만들기
- concat 메서드를 사용한 배열이 앞에 추가되고, 인수로 전달된 배열이 뒤에 추가됨
- concat : 내부적으로 하나의 새로운 배열을 만들고 두개의 배열 요소를 새로운 배열에 집어넣음
7) 배열 요소 삭제, 추가하기 : Array.prototype.splice
1 2 3 4 5 6 | var arr = []; for(var i=0; i<20; i++) arr[i] = i+1; arr.splice(0, 10, 30,31,32); console.log(arr); // (13) [30, 31, 32, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] | cs |
- splice 메서드 : 첫번째 인수 - 변경 시작 인덱스, 두번째 - 시작 인덱스부터 삭제할 길이, 세번째 인수부터- 배열에 추가할 요소
- 배열 요소를 변경하는 용도로 사용되는 메서드
8) 직관적으로 배열 요소 추가하기 : Array.prototype.push
1 2 3 4 5 6 7 8 | var arr = []; for(var i=0; i<10; i++) arr[i] = i+1; arr.push(11); // === arr[arr.length] = 11; console.log(arr); // (11) [1,2,3,4,5,6,7,8,9,10,11] | cs |
- 배열(객체)의 length 프로퍼티를 사용해 추가 단계를 짜지않고, 직관적인 코드로 배열 요소 추가하기
- 배열 요소 끝에 추가됨
9) 첫머리에 배열 요소 추가하기
1 2 3 4 5 6 7 8 9 | var arr = [1,2,3,4,5]; var length = arr.length; var newnum = 0; for(var i=length; i>=0; i--) arr[i] = arr[i-1]; arr[0] = newnum; console.log(arr); // (6) [0,1,2,3,4,5] | cs |
- 끝으로 하나씩 밀어야하기때문에 끝에서부터 뒤로 밀기
10) 직관적으로 첫머리에 배열 요소 추가하기 : Array.prototype.unshift
1 2 3 4 | var arr = [1,2,3,4,5]; arr.unshift(-1, 0); console.log(arr); // (7) [-1,0,1,2,3,4,5] | cs |
- 내부 동작은 9번과 같겠지만 직관적으로 추가하기
11) 마지막 배열 요소 삭제하기 + 꺼내기 : Array.prototype.pop
1 2 3 | var arr = [1,2,3,4,5]; arr.pop(); console.log(arr); // (4) [1,2,3,4] | cs |
- pop 메서드를 사용하면 배열 요소 마지막 요소가 삭제됨
- 튀어나오다
12) 첫번째 배열 요소 삭제하기 + 꺼내기
1 2 3 4 5 6 7 8 9 10 | var arr = [1,2,3,4,5]; for(var i=0; i<arr.length; i++) arr[i] = arr[i+1]; console.log(arr); // (5) [2,3,4,5,undefined] arr.pop(arr[arr.length]); console.log(arr); // (4) [2,3,4,5] | cs |
- 첫번째 요소부터 뒤로 밀어야하기때문에 첫번째 요소부터 시작
- 맨 뒤에 불필요한 요소가 저장되는 것과 같음 : 지워줘야함
13) 직관적으로 첫번째 배열 요소 삭제하기 + 꺼내기 : Array.prototype.shift
1 2 3 4 | var arr = [1,2,3,4,5]; arr.shift(); console.log(arr); // (4) [2,3,4,5] | cs |
14) splice를 이용해 중간에 배열요소 추가, 삭제하기 : Array.prototype.splice
1 2 3 4 5 6 7 | var arr = [1,2,3,4,5,6,7,8,9,10]; arr.splice(5, 0, 6,6,6,6,6); console.log(arr); // (15) [1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 7, 8, 9, 10] arr.splice(6, 5); console.log(arr); // (10) [1,2,3,4,5,6,7,8,9,10] | cs |
- splice(시작인덱스, 삭제할갯수, 추가할요소, --------) : 삭제할 갯수 자리에 0이 들어가면 요소를 추가하는 것
- 추가할 요소를 전달하지않으면 삭제
15) 배열 요소 정렬하기 : Array.prototype.sort
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | var nums = [5, 2, 1, 4, 3]; nums.sort(function(a, b){ return a-b; }); // (5) [1,2,3,4,5] var person = [ { name: "jinbro", age: 26 }, { name: "james", age: 30 }, { name: "brew", age: 81 }, { name: "grand", age: 11 } ]; person.sort(function(a, b){ return a.age - b.age; }); // (4) [Object, Object, Object, Object] for(var i=0; i<person.length; i++){ console.log(person[i]); // 나이 순으로 정렬됨 } | cs |
- sort 함수 : 배열 요소를 문자열로 변환한 뒤 유니코드 포인트 순서로 문자열을 비교하여 정렬
- sort 함수의 인자로 정수를 비교하는 함수를 넘겨줄 때 문자열로 변환하지않고 제대로 정렬함
- 비교 함수 : a와 b 두 정수를 받아 뺄셈한 결과가 a와 b의 비교 결과, a-b 결과 양수 : a, a-b 결과 0 : 같음, a-b 결과 음수 : b
- 배열 요소를 객체로 두고, 객체의 특정 프로퍼티를 기준으로 정렬할 수 있음
16) 배열 요소 역순으로 정렬하기 : Array.prototype.reverse
1 2 3 4 5 6 7 8 | var nums = [1,2,3,4,5]; nums.reverse(); console.log(nums); // (5) [5,4,3,2,1] var charArr = ['b', 'a', 'z', 'e', 'f']; charArr.sort().reverse().join(''); // "zfeba" } | cs |
- 배열 요소를 뒤죽박죽 섞으면 제대로 동작안함 : sort와 마찬가지인듯
- sort 시킨후 reverse 하면됨
17) 배열 요소마다 함수 실행시키기 : Array.prototype.forEach
1 2 3 4 5 6 7 | var arr = [1,2,3,4,5,6,7,8,9,10]; arr.forEach(function(element, index, array){ console.log(element + ", " + index + ", " + array); if(index === 4) break; // Syntax Error }); | cs |
- 배열 요소마다 어떤 함수를 적용시켜야할 때 forEach 함수를 사용
- forEach 함수의 파라미터 함수(콜백함수 - 배열 요소 하나씩 돌때마다 호출되는 함수) element, index, array를 가짐
- element : 현재 배열 요소
- index : 현재 배열 요소의 배열에서 인덱스
- array : forEach 함수가 적용되고 있는 배열
- index, array 파라미터는 생략해도 됨
- forEach 함수는 예외 발생이외에 중간에 멈출 수 없음 : break 문 안됨
18) 모든 배열 요소가 함수 실행 구문 테스트에 통과하는지 테스트하기 : Array.prototype.every
1 2 3 4 5 6 | function isEven(element, index, array){ return element % 2 == 0; } var arr = [1, 2, 3, 4, 5, 6]; // 1에서 멈춤, false arr.every(isEven); | cs |
- every 함수의 인수로 전달되는 함수 실행구문은 불리언(true/false) 결과를 리턴해야함
- every 함수의 인수로 전달되는 콜백함수는 forEach의 파라미터 함수와 같음
- element : 현재 처리 중인 배열 요소
- index : 현재 처리 중인 배열 요소의 인덱스
- array : every가 호출한 배열
- index, array 파라미터는 생략해도 됨
- 모든 요소가 콜백함수의 실행구문(조건)을 통과하지못할 때 false, 통과한다면 true
- 검사 중간 false가 나올 경우 멈추고 결과값을 리턴(&&)
19) 일부 배열 요소가 함수 실행 구문 테스트에 통과하는지 테스트하기 : Array.prototype.some
1 2 3 4 5 6 | var arr = [2,5,7,9,11]; var isIncludeEven = arr.some(function(element, idx, arr){ return element%2 === 0; }); | cs |
- every와는 동일하지만 다름 : every는 true 조건이 &&라면, some은 true 조건이 ||(콜백함수의 실행문)
- 배열 요소 중 1개 이상이 true라면 true를 반환
- 하나라도 true라면 바로 멈추고 true를 반환함
- 입력값을 받고, 배열 내에 입력값이 존재하는지 체크할 때 사용하면 됨
20) 배열 요소 하나의 값으로 합하기 : Array.prototype.reduce / Array.prototype.reduceRight
1 2 3 4 5 6 7 8 9 10 11 12 | function add(previous, current, idx, arr){ return previous + current; } var arr = [1,2,3,4,5]; var sum = arr.reduce(add); console.log(sum); // 15 var arr2 = [[0, 1], [2, 3], [4, 5]]; arr2.reduce(function(a, b){ return a.concat(b); }) | cs |
- reduce의 파라미터로 콜백함수를 지정함 : 콜백함수가 배열 요소 하나씩 불러와(배열 길이만큼) 더하고 그 결과값을 리턴함
- reduce의 파라미터로 선택사항 초기값 지정할 수 있음 : previousValue에 해당하는 값 지정가능(지정하지않으면 배열 첫번째 요소)
- 콜백함수의 파라미터는 4개가 있음 : previousVal, currentVal, index, array
- previousVal : reduce 초기값(두번째 파라미터) 없다면 배열의 첫번째 요소가 첫번째로 값 지정, 이후 부턴 배열 요소의 합 변수로 쓰임
- currentVal : 현재 배열 요소 중 1개의 값 - 순서대로
- index : 현재 배열 요소의 인덱스
- array : reduce를 호출한 배열
- 합을 계속해서 합치는 것 : 콜백함수는 이벤트큐 - 이벤트루프 -
- 2차원 배열을 1차원으로 만들기 : concat 함수 활용
- Array.prototype.reduceRight : reduce와 동일하지만 합치는 방향이 거꾸로부터 시작(문자열을 합칠 경우 중요)
21) 배열 요소마다 함수 실행시키기 후 결과를 새로운 배열 삽입 : Array.prototype.map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var arr = [78, 55, 47, 62, 91]; var newArr = arr.map(function(currentVal, idx, arr){ return currentVal + 5; }); console.log(arr); // (5) [78, 55, 47, 62, 91] console.log(newArr); // (5) [83, 60, 52, 67, 96] var objArr = [ { name: "jinbro", age: 26 }, { name: "james", age: 30 }, { name: "brew", age: 81 }, { name: "grand", age: 11 } ] var newObjArr = objArr.map(function(currentObj){ var newObj = {}; newObj.name = currentObj.name; newObj.age = currentObj.age + 1; return newObj; }); | cs |
- forEach와 같지만 새로운 배열을 생성하는 것에서는 다름
- 뭐 어떤 버프를 주지만 일시적으로 버프를 줄 때? : 새로운 배열을 생성함, 기존 배열은 그대로 유지
22) 배열 요소 중 조건에 맞는 요소만 추려 새로운 배열 만들기 : Array.prototype.filter
1 2 3 4 5 6 7 8 9 10 11 | var objArr = [ { name: "jinbro", grade: 87 }, { name: "james", grade : 92 }, { name: "brew", grade : 81 }, { name: "grand", grade : 75 } ] var newObjArr = objArr.filter(function(currentObj){ return currentObj.grade >= 85; }); // jinbro와 james만이 점수가 85점 이상이므로 새로운 배열의 요소로 추가됨 | cs |
- every와 비슷하지만 콜백함수 내부 구문(조건 구문)에 맞는 요소만 추려 새로운 배열을 생성하는 것이 다름
- json에서 유효한 값만 골라내기 : 위처럼 무효값을 걸러내어(조건문) 유효값만 골라내기
[배열 확장하기 - 이차원 배열. ... 다차원배열]
- 자바스크립트는 기본적으로 일차원 배열만 지원함
- 액셀 스프레드시트를 생각하면 쉬움
- 가로 방향(row, 행) / 세로 방향(column, 열)
- row를 셀 때에는 세로 방향 갯수를 세고, column을 셀 때에는 가로 방향 갯수를 세면 됨
- 이차원배열 : 배열에 배열을 중첩함으로서 구현 가능
1 2 3 4 5 | var arr = []; var rows = 5; for(var i=0; i<5; i++) arr[i] = [i, i+1]; // 임의로 배열 요소를 넣음 : 확인을 위해서 | cs |
- arr[0] : 1행 내용 출력, arr[2][1] : 3행의 두번째 요소 출력
- 행 기준으로 데이터 처리하기 : 사람 기준으로 평균값 내기(임의로 마지막행에 avg 추가)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var grades = [[89, 77, 78], [76, 82, 81], [91, 94, 98]] var total = 0; var avg = 0.0; for(var row=0; row<grades.length; row++){ for(var col=0; col<grades[row].length; col++){ total += grades[row][col]; } avg = (total / grades[row].length).toFixed(2); grades[row].push(avg); total = 0; avg = 0.0; } | cs |
- 사람 기준(행)으로 데이터를 처리함
- toFixed 함수로 소수점 2자리까지만 표시하도록
- 열 기준으로 데이터 처리하기 : 과목 기준으로 평균값 내기(임의로 새로운 배열에 과목당 avg를 요소로)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var grades = [[89, 77, 78], [76, 82, 81], [91, 94, 98]] var total = 0; var avg = 0.0; var avgGrades = []; for(var col=0; col<grades.length; col++){ for(var row=0; row<grades[col].length; row++){ total += grades[row][col]; } avg = (total / grades[col].length).toFixed(2); avgGrades[col] = avg; total = 0; avg = 0.0; } | cs |
- 과목별 점수를 기준으로 하기때문에 과목별 점수를 큰 기준(반복문 바깥)으로
- 반복문의 순서만 바꿔주면 무엇을 기준으로 하냐가 달라짐
- 길이가 둘쭉날쭉한 배열 : 자바스크립트 배열 행의 길이는 정확하게 알 수 있음(length 프로퍼티)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var grades = [[97, 85], [92, 85, 92], [96, 92, 98, 100]] var total = 0; var avg = 0.0; for(var row=0; row<grades.length; row++){ for(var col=0; col<grades[row].length; col++){ total += grades[row][col]; } avg = (total / grades[row].length).toFixed(2); grades[row].push(avg) total = 0; avg = 0.0; } | cs |
- 배열 행의 열 길이가 다르다하더라도 배열 객체의 length 프로퍼티가 있기때문에 상관x
[참조자료]
- MDN, Array.prototype : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype
- O'REILLY, 자바스크립트 자료구조와 알고리즘 : http://www.yes24.com/24/goods/14419692?scode=032&OzSrank=1
- ECMA, ECMAScript5 : http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.7
'javascript' 카테고리의 다른 글
[API] nodejs 파일 업로드 모듈 (0) | 2017.05.23 |
---|---|
[웹기본개념] 집에서 웹서버 운영하기 (0) | 2017.05.22 |
[자바스크립트] this 바인딩 포스팅 AS - 바인딩 종류 (0) | 2017.05.20 |
[자바스크립트] 잠깐 쉬어가기 : 자바스크립트 특징 (0) | 2017.05.18 |
[자바스크립트] 객체 그리고 프로토타입 (0) | 2017.05.17 |
댓글