2015년 3월 10일 화요일

[JavaScript] 자바스크립트 Array(배열)

자바스크립트는 여러가지 built-in Object를 내장하고 있는데, 그중 Array(배열) 개체은 사실상 가장 기초적이며 가장 다양하게 쓰이는 개체일 것 이다.
같은 타입(Type)의 자료를 저장해야하는 타 프로그래밍 언어와는 달리, 자바스크립트(ECMAScript)는 배열에 다른 자료형들을 저장하는게 가능하다. 즉, Array(배열) 1개에, boolean 값, string 값, number 값, 등을 모두 저장할 수 있다는 말이다. Array 자료형은 총 4294967295개의 데이터를 저장할 수 있다. 만약 이 이상을 저장하려 한다면 에러가 발생하게 될 것이다.

Array(배열)은 2가지 방식으로 선언될 수 있다.

// Array Constructor 를 이용하는 방법

var arrayConstructorDemo1 = new Array(); // empty Array를 생성
var arrayConstructorDemo2 = new Array(3); // 3의 크기를 가진 Array를 생성
var arrayConstructorDemo3 = new Array("test", true, 33); // 원하는 데이터로 생성

// Array Literal Notation을 사용하는 방법
var arrayLiteralDemo1 = []; // empty Array를 생성한다.
var arrayLiteralDemo2 = [ "test", true, 33 ];
// "test", true, 33 3개의 데이터를 가진
// 어레이를 생성 ArrayConstructorDemo3와 같은 결과

// 아래의 Array Literal Notation 사용은 작동하나, 브라우져 환경에 따라 에러를 생성할 수 있으니, 사용을 자제하도록하자.

var arrayLiteralDemo3 = [ 1, 2, 3, ]; 
// 1,2,3값을 가진 크기 3 또는 4(네번째는 undefined 값)의 배열을 생성한다.

var arrayLiteralDemo4 = [ , , , ]; 
// 3개 또는 4개의 undefined 값을 가진 array를 생성한다

Array(배열)의 선언 후에 내부 값에 접근(읽기/쓰기)하기 위해서는 [,] 사각괄호안에 접근하고 싶은 값의 index를 넣으면 된다.
참고로 배열의 index는 언제나 0 부터 시작하며, 배열의 크기는 length프로퍼티에 접근하여 알 수 있다.


var arrayConstructorDemo = new Array("test", true, 33);

console.log(arrayConstructorDemo[0]); //"test"
console.log(arrayConstructorDemo[1]); //true
console.log(arrayConstructorDemo[2]); //33

//같은 방식으로 값을 변경할 수 있다.

arrayConstructorDemo[0] = "complete";
arrayConstructorDemo[1] = 13;
arrayConstructorDemo[2] = false;

console.log(arrayConstructorDemo[0]); // complete
console.log(arrayConstructorDemo[1]); // 13
console.log(arrayConstructorDemo[2]); // false

console.log(arrayConstructorDemo.length);// 배열의 크기 확인

//배열의 new index에 새로운 값을 삽입한다.
arrayConstructorDemo[4] = "new Index"; // index 4에 새로운 값을 삽입한다
console.log(arrayConstructorDemo[4]); // new Index
console.log(arrayConstructorDemo.length);// 5

//배열의 크기를 2로 줄여보자.
arrayConstructorDemo.length = 2;
console.log(arrayConstructorDemo[4]); // undefined
console.log(arrayConstructorDemo[2]); // undefined

//다시 배열의 크기를 5로 늘릴경우
arrayConstructorDemo.length = 5;
console.log(arrayConstructorDemo[4]); // undefined
console.log(arrayConstructorDemo[3]); // undefined
console.log(arrayConstructorDemo[2]); // undefined

Array의 크기는 매우 동적이며, 만약 위의 코드처럼, 사이즈 3의 배열에 존재하지 않는 인덱스인 4에 새로운 값을 삽입하려 한다면, 자바스크립트 엔진은 자동으로 배열의 크기를 새로운 index에 알맞게 증가 시키고, 값을 삽입하게 된다.

length 프로퍼티는 read-only가 아니기 때문에, array의 크기를 조절하는데도 사용이 가능하다.
배열의 크기를 줄일 경우에는, 줄어든 배열에 포함되지 않는 index 값에 접근하게되면 언제나 undefined 값을 반환하게 된다.

배열의 크기를 늘리게 될 경우에도 마찬가지로 배열에 새로들어오게된 index들은 undefined 값을 가지게 된다.

Array.isArray() 메소드


Array.isArray() 메소드는 괄호안에 주어진 변수가 Array 개체인지를 확인하는 메소드 이다. 이 메소드는 ECMAScript 5에서부터 적용되기 시작했다. 이 메소드가 적용된 가장 큰 이유는 instanceof 연산자가 가지는 한계 때문이였는데, 1개의 global context를 전제하는 instanceof 연산자는 대부분 multi-frame DOM 환경에서 제대로 작동하지 않는다는 한계를 가지고 있었다. 이 때문에 총 2개의 global context를 가지는 경우에는, instanceof 연산자로 다른 global context의 Array 개채를 계산하게 되면, false 값을 얻게 된다. 이 한계를 넘기 위해 나온게 바로 Array.isArray 메소드 이다.

아래와 같이 사용할 수 있다.


if (Array.isArray(arrayConstructorDemo)) {
    console.log("This is Array");
}

Stack & Queue


자바스크립트 Array(배열)은 StackQueue 설정을 제공한다. 즉, 기본적으로 제공되는 메소드들로 배열을 Stack 또는 Queue로 사용하는게 가능하다. Stack 과 Queue는 LIFO, FIFO로 표현되는 자료 구조로, 그 컨셉을 자세히 알고 싶으면 앞의 링크를 클릭 해보도록 하자.

Stack

push 메소드를 이용해서 새로운 데이터를 삽입해 array 의 크기값을 반환하고, pop 메소드를 이용해서 가장 최근에 삽입된 데이터를 빼내온다.


var arrayStackDemo = new Array();

var size = arrayStackDemo.push("Demo1", "Demo2");

console.log(size);// 2

size = arrayStackDemo.push("Demo3");

console.log(size);// 3

var topStack = arrayStackDemo.pop();

console.log(topStack); // Demo3

console.log(arrayStackDemo.length); // 2


Queue

Stack과 같이 push 메소드를 이용해 배열의 끝에 새 데이터를 삽입한다.
원래 Queue의 값을 얻어오는 메소드도 이름이 "pop"이나 이미 Stack을 구현하는데 사용되버렸기 때문에 "shift"메소드를 이용해 배열에 값을 삽입힌다.
또한, "unshift" 메소드를 이용해 배열의 처음에 새 데이터를 삽입할 수도 있다


var arrayQueueDemo = new Array("Demo0");

var size = arrayQueueDemo.push("Demo1", "Demo2");

console.log(size);// 3

size = arrayQueueDemo.push("Demo3");

console.log(size);// 4

var firstQueue = arrayQueueDemo.shift();

console.log(firstQueue); // Demo0

console.log(arrayQueueDemo.length); // 3

size = arrayQueueDemo.unshift("newValue");

console.log(size);// 4

firstQueue = arrayQueueDemo.shift();

console.log(firstQueue); // newValue

Sort & Reverse


자바스크립트의 Array 개체는 기본적으로 배열을 재정렬할 수 있는 메소드들을 제공한다.

Reverse

Reverse 메소드는 이름에서도 알 수 있듯이, 배열을 뒤짚는 메소드 이다.


var a = [ 0, 1, 2, 3, 4, 5 ];
a.reverse();

console.log(a);// [ 5, 4, 3, 2, 1, 0 ]

Sort

Sort 메소드는 Array를 정렬한다. 하지만 기본적으로 Sort 메소드는 배열의 개체들이 String 타입이라 전제하에 정렬하기 때문에, 수의 경우에도 마찬가지로 문자열처럼 [1, 12, 13, 2] 정렬된다.


var a = [ 0, 1, 12, 13, 2 ];
a.sort();

console.log(a);// [ 0, 1, 12, 13, 2 ]

이를 해결하기 위해서 sort메소드의 파라미터로 비교함수를 넣어 줄 수 있다.
사용법은 아래와 같다.


function comparator(a, b) {
    if (a > b) {
 return 1;
    } else
 (a < b)
    {
 return -1;
    }
    return 0;
}

var a = [ 0, 1, 12, 13, 2, 13 ];
a.sort(comparator);

console.log(a);// [ 0, 1, 12, 13, 13, 2 ]

Concat


각기 다른 여러개의 Array를 합쳐 새로운 Array 개체를 생성한다


var a = [ "a", "b", "c" ];
var b = [ "d", "e", "f" ];

var c = a.concat(b, "g", [ "e", "f", "g" ])

console.log(a);// [ 'a', 'b', 'c' ]
console.log(b);// [ 'd', 'e', 'f' ]
console.log(c);// [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'e', 'f', 'g' ]

Splice


Array 개체에서 주어진 index의 데이터들을 가져와 새로운 Array를 생성한다. 새로운 Array를 생성하며 추가적으로 원래 Array에 새로운에에 데이터를 삽입할 수도 있다. 즉 원래 Array에서는 데이터를 삭제하며, 새로운 삭제된 데이터들로 새로운 Array를 생성한다.


array.splice(start, deletecount, items)

start에 삭제할 범위의 첫번째 index
deletecount에는 첫번째 index인 start를 포함해 삭제할 엘리맨트의 갯수
items에는 삭제후 삭제된 index에 삽입할 데이터 어레이, 또는 데이터.

var a = [ "a", "b", "c" ];
var b = [ "d", "e", "f" ];

var c = a.splice(0, 2);
b.splice(0, 2)

console.log(a);// [ 'c' ]
console.log(b);// [ 'f' ]
console.log(c);// [ 'a', 'b' ]

c.splice(0, 0, "new VAL");

console.log(c);// [ 'new VAL', 'a', 'b' ]

indexOf & lastIndexOf


indexOf와 lastIndexOf 메소드는 둘다 array에서 주어진 데이터를 검색 후, 그 데이터가 저장된 위치, 즉 index를 리턴한다. 아무것도 찾을 수 없을시에는 -1값을 리턴한다.

*indexOf는 배열의 처음(0)부터 검색하지만, lastIndexOf는 배열의 끝(length-1)부터 검색하게 된다.


var a = [ "a", "b", "c", "a" ];

console.log(a.indexOf("a"));// 0
console.log(a.lastIndexOf("a"));// 3
console.log(a.indexOf("t"));// -1

반복문(Iterative Method)


자바스크립의 Array는 기본적으로 5가지 함수 반복문을 제공한다.

  • foreach()
    • Array의 모든 엘리멘트를 파라미터로 주어진 함수에 따라 계산한다. 하지만 어떠한 값도 반환하지 않는다
  • every()
    • Array의 모든 엘리멘트를 파라미터로 주어진 함수에 따라 계산한다. 만약 모든 계산에서 true 값이 나왔다면 true 값을 리턴한다
  • some()
    • Array의 모든 엘리멘트를 파라미터로 주어진 함수에 따라 계산한다. 그 중 1개의  계산에서 true 값이 나왔다면 true 값을 리턴한다
  • filter()
    • Array의 모든 엘리멘트를 파라미터로 주어진 함수에 따라 계산한다. 계산에서 true 값을 리턴하는 엘리멘트의 배열을 리턴한다
  • map()
    • Array의 모든 엘리멘트를 파라미터로 주어진 함수에 따라 계산한다. 각각 계산의 결과값으로 만들어진 배열을 리턴한다

파라미터로 주어지는 함수의 시그니쳐는 언제나


function name(item(데이터값), index(인덱스), array(배열))

이며 사용법은 아래와 같다.


function func(item, index, array) {
    if (item % 2 == 0) {
 return true;
    }
    return false;
}

var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
console.log(a);// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

var b = a.every(func);
console.log(b);// false

var c = a.filter(func);
console.log(c); // [ 2, 4, 6, 8, 10 ]

var d = a.some(func);
console.log(d);// true

var e = a.map(func);
console.log(e);// [ false, true, false, true, false, true, false, true, false, true ]

var f = a.forEach(func);
console.log(f);// undefined
//아무것도 반환하지 않기 때문에 f의 값은 undefined 이다.


Reduce & ReduceRight


Reduce 메소드란 ECMAScript 5에서 새로 추가된 기능으로 배열의 모든 데이터에 대해 파라미터로 주어진 함수를 반복해, 최종값을 얻어내는 메소드 이다.
Reduce 메소드는 Array의 처음부터 함수를 시작하며, ReduceRight 메소드는 Array의 끝부터 메소드를 시작한다.
Reduce 와 ReduceRight 메소드 둘 다 파라미터로 받는 함수는 다음과 같은 Function Signature를 가진다.


function func(prev, cur, index, array)
//prev 는 바로 전 반복문까지의 최종 값이며, cur 은 현재 반복문의 순서에 있는 배열내의 데이터값이다.
//index 는 현재 데이터값의 배열 인덱스를 의미하며, array는 현재 배열 개체를 의미한다.

사용법은 아래와 같다.


function func(prev, cur, index, array) {
    if (cur % 2 == 0) {
 return prev - cur;
    }
    return prev + cur;
}

var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
console.log(a.reduce(func));// -5
// 위 reduce메소드의 계산과정은 아래와 같다.
// 1 - 2 - 1 + 3 + 2 - 4 - 2 + 5 + 3 - 6 - 3 + 7 + 4 - 8 - 4 + 9 + 5 - 10

console.log(a.reduceRight(func));// 15
// 위 reduceRight메소드의 계산과정은 아래와 같다.
// 10 + 9 + 19 - 8 + 11 + 7 + 18 - 6 + 12 + 5 + 17 - 4 + 13 + 3 + 16 - 2 + 14 + 1

댓글 1개: