배열(Array)
배열생성
[]를 이용해 배열변수를 선언하는게 가장 간단한 방법이다.
var numbers = [];
console.log(numbers.length); // 0
var numbers = [1,2,3,4];
console.log(numbers.length); // 4
Array 생성자를 호출하여 배열을 만들수도 있다.
var numbers = new Array();
console.log(numbers.length); // 0
var numbers = new Array(1,2,3,4);
console.log(numbers.length); // 4
Array생성자에 한개의 인자(정수)를 넣으면 정수만큼의 길이가 지정된 배열을 만들 수 있다.
var numbers = new Array(10);
console.log(numbers.length) // 10
다른 데이터 타입의 생성자와 기본형과는 달리 new Array() 와 []는 내부적으로 같은 동작을 취한다.
var arr = [];
console.log(arr.constructor === Array);
console.log(arr instanceof Array);
배열 요소 접근 & 값 할당
// 1~100까지 정수를 배열에 할당하는 루프
var nums = [],
i;
for (i = 0; i < 100; i++){
nums[i] = i+1;
}
// nums배열내 모든 값을 더하는 루프
var nums = [1,2,3,5,8,13,21],
sum = 0,
i;
for (i = 0; i < nums.length; i++){
sum += nums[i];
}
console.log(sum); // 53
문자열을 배열로 만들수 있다.
var sentence = "the quick brown fox jumped over the lazy dog",
words = sentence.split(" "),
i;
for(i = 0; i < words.length; i++){
console.log("word "+i+": "+words[i]);
}
word 0: the
word 1: quick
word 2: brown
word 3: fox
word 4: jumped
word 5: over
word 6: the
word 7: lazy
word 8: dog
배열 전체에 적용되는 기능
배열을 다른 배열로 할당할 때 실제로는 할당된 배열의 레퍼런스를 할당한다. 따라서 원래 배열을 바꾸면 할당된 배열도 바뀐다. 이과 같은 동작을 얕은 복사(shallow coppy)라고 한다.
Shallow copy
var nums = [1,2,3],
same = nums;
nums[0] = 100;
console.log(same[0]); // 100
Deep copy
var nums = [],
same = [],
i;
function copy(arr1, arr2){
for (let i = 0; i < arr1.length; i++){
arr2[i] = arr1[i];
}
}
for (i = 0; i < 100; i++){
nums[i] = i+1;
}
copy(nums, same);
nums[0] = 100;
console.log(same[0]); // 1
접근자 함수
- <array>.indexOf() : 첫번째 인덱스 (0에서부터)
- <array>.lastIndexOf() : 마지막 인덱스 (0에서부터)
var names = ["apple", "banana", "cherry", "apple"],
input = prompt("Enter a name to search for :"),
firstPos = names.indexOf(input),
lastPos = names.lastIndexOf(input);
if(position >= 0){
console.log("Found "+input+" at position "+firstPos);
console.log("Last Position "+input+" at position "+lastPos);
}else{
console.log(input+" not found in array");
}
- <array>.toString() / <array>.join() : 배열을 문자열 형식으로 반환.
var names = ["apple", "banana", "cherry", "apple"],
namestr = names.join();
console.log(namestr); // apple, banana, cherry, apple
namestr = names.toString();
console.log(namestr); // apple, banana, cherry, apple
- <array>.concat(<another_array>) : 두 개 이상의 배열을 합쳐 새배열을 만든다.
- <array>.splice(index, count) : 기존배열의 서브셋으로 새배열을 만든다.
var fruits = ["apple", "banana", "cherry"],
vegetables = ["cucumber", "garlic"],
cart1, cart2;
cart1 = fruits.concat(vegetables); // [apple, banana, cherry, cucumber, garlic]
cart2 = fruits.splice(1,2); // ["banana", "cherry"]
- array.splice(start, deleteCount[, item1, ... itemN])
// splice함수의 또 다른 사용.
var nums = [1,2,3,7,8];
nums.splice(3,0,4,5,6);
// [] 삭제된 값이 없을경우 빈배열을 리턴한다.
// nums -> [1,2,3,4,5,6,7,8]
변형자 함수
- <array>.push(element1, ..., elementN) : 배열의 끝에 엘리먼트를 추가한다.
- <array>.unshift(element1, ..., elementN) : 배열의 끝에 엘리먼트를 추가한다.
var fruits = ["apple", "banana", "cherry"];
fruits.push("tomato");
// 4
// fruits -> ["apple", "banana", "cherry", "tomato"];
fruits.unshift("coconut");
// 5
// ["coconut", "apple", "banana", "cherry", "tomato"];
push(), unshift()함수는 결과값으로 length를 반환한다.
- <array>.pop() : 배열에서 마지막 요소를 제거하고, 그 값을 반환한다.
- <array>.shift() : 0번째 위치의 요소를 제거하고, 그 값을 반환한다.
var fruits = ["apple", "banana", "cherry"];
fruits.pop();
// cherry
// fruits -> ["apple", "banana"];
fruits.shift();
// apple
// ["banana"];
- <array>.reverse() : 배열의 element들을 내림차순으로 정렬하고 배열반환.
- <array>.sort() : 배열의 element들을 오름차순으로 정렬하고 배열반환.
var chars = ["a","c","b","e","d"],
nums = [1,30,20,10,3,2];
chars.sort(); // ["a","b","c","d","e"]
chars.reverse(); // ["e","d","c","b","a"]
nums.sort(); // [1,10,2,20,3,30] ??
정렬 순서는 문자열 유니코드 코드 포인트에 따른다. 즉, 10이 2보다 유니코드 코드포인트 상에서 빠르기 때문에 앞에 위치한다.
- <array>.sort(compareFunction) : 정렬 순서를 정의하는 함수를 지정합니다.
function compareNumbers(num1,num2){
return num1 - num2;
}
var nums = [1,30,20,10,3,2];
nums.sort(compareNumbers); // [1,2,3,10,20,30];
뺄셈의 결과가 음수라는 것은 num1이 num2보다 작다는것을 의미하며, 양수라는 것은 num1이 num2보다 크다는것을 의미 한다. 이것을 기준으로 정렬.
반복자 함수
- <array>.forEach(callback[, thisArg])
var nums = [1,2,3,4,5];
nums.forEach(function(n){
console.log(n);
});
1
2
3
4
5
- <array>.every(callback[, thisArg]) : 배열의 모든 요소가 제공한 함수로 구현된 테스트를 통과하는지를 테스트한다.
- <array>.some(callback[, thisArg]) : 배열의 요소중 한 요소라도 제공한 함수로 구현된 테스트를 통과한다면 true를 반환한다.
function isEven(num){
return num % 2 == 0;
}
var nums = [2,4,6,7,8,10];
var everyEven = nums.every(isEven);
var someEven = nums.some(isEven);
if(everyEven){
console.log("all numbers are even");
}else if(someEven){
console.log("some numbers are even");
}else{
console.log("not all numbers are even");
}
- <array>.reduce(callback[, initialValue]) : 누산기(accumulator) 및 배열의 각 값(좌에서 우로)에 대해 (누산된) 한 값으로 줄도록 함수를 적용합니다.
- <array>.reduceRight(callback[, initialValue]) : 누산기에 대해 함수를 적용할때 배열의 각값이 reduce와는 반대방향으로 (오른쪽에서 왼쪽) 단일값으로 줄여나간다.
function add(runnungTotal, currentValue){
return runningTotal + currentValue;
}
var nums = [1,2,3,4,5,6,7,8,9,10],
strs = ["javascript", " love ", "I"],
sum;
sum = nums.reduce(add);
console.log(sum); // 55
sum = strs.reduceRight(add);
console.log(sum); // I love javascript
add(1,2) -> 3
add(3,3) -> 6
add(6,4) -> 10
add(10,5) -> 15
add(21,6) -> 21
add(21,7) -> 28
add(28,8) -> 36
add(36,9) -> 45
add(45,10) -> 55
- map() : forEach()와 비슷하지만 , 배열 자체를 변환 시키지 않고 새로운 배열을 반환하는 반복자 함수이다.
function curve(grade) {
return grade += 5;
}
var grades = [77, 65, 81, 92, 83],
newgrades = grades.map(curve);
console.log(newgrades); // [82, 70, 86, 97 88]
console.log(grades); // [77, 65, 81, 92, 83]
- filter() : every()와 비슷하지만, Boolean을 반환 하는게 아니라, 조건을 만족하는 요소를 포함하는 새로운 배열을 반환하는 반복자 함수이다.
function passing(num){
return num >= 60;
}
var grades = [],
passGrades, i;
for(i=0; i<20; i++){
grades[i] = Math.floor(Math.random() * 101);
}
passGrades = grades.filter(passing);
passGrades
[99, 90, 89, 89, 70, 88, 66, 94, 87, 69, 87]
grades
[99, 90, 89, 89, 4, 33, 5, 70, 88, 32, 33, 66, 45, 5, 94, 87, 20, 8, 69, 87]
이차원배열과 다차원 배열
이차원 배열은 행과 열을 가진 스프레드 시트 같은 구조이다. 이차원 배열을 만들려면 배열을 만든 다음 각 요소를 배열로 만들어야 한다.
- 행과 열을 가진 배열 만들기
var twod = [],
rows = 5,
i;
for (i = 0; i < rows; i++){
twod[i] = [];
}
- 더글라스 클락포드의 예제
Array.matrix = function(numrows, numcols, initial){
var arr = [];
for (var i = 0; i < numrows; i++){
var columns = [];
for(var j = 0; j < numcols; j++){
conlums[j] = initial;
}
arr[i] = columns;
}
return arr;
}
var nums = Array.matrix(5,5,0);
console.log(nums[1][1]); // 0
var names = Array.matrix(3,3,"");
names[1][2] = "Joe"
console.log(names[1][2]); // "Joe"
- 이차원 배열 요소 처리하기
var grades = [[89,77,78],[76, 82, 81],[91, 94, 89]],
total = 0,
average = 0.0,
row, col;
for(row = 0; row<grades.length; row++){
for (col = 0; col<grades[row].length; col++){
total += grades[row][col];
}
average = total/grades[row].length;
console.log("Student" + parseInt(row + 1) + " averages: " + average.toFixed(2));
total = 0;
average = 0.0;
}
Student 1 average: 81.33
Student 2 average: 79.67
Student 3 average: 91.33
- 들쭉날쭉한 배열
var grades = [[89,77],[76, 82, 81],[91, 94, 89, 99]],
total = 0,
average = 0.0,
row, col;
for(row = 0; row<grades.length; row++){
for (col = 0; col<grades[row].length; col++){
total += grades[row][col];
}
average = total/grades[row].length;
console.log("Student" + parseInt(row + 1) + " averages: " + average.toFixed(2));
total = 0;
average = 0.0;
}
Student 1 average: 83.00
Student 2 average: 79.67
Student 3 average: 93.25
객체를 요소로 포함하는 배열
function Point(x,y){
this.x = x;
this.y = y;
}
function displayPts(arr){
for (var i=0; i<arr.length; i++){
console.log(arr[i].x + "," + arr[i].y)
}
}
var p1 = new Point(1,2),
p2 = new Point(3,5),
p3 = new Point(2,8),
p4 = new Point(4,4),
p5 = new Point(12,-3),
points = [p1,p2,p3,p4],
i;
for(i = 0; i<points.length; i++){
console.log("Point " + parseInt(i+1) + ": " +points[i].x + ", " + points[i].y);
}
points.push(p5);
// [p1,p2,p3,p4,p5] -> [Point, Point, Point, Point, Point]
// 0 Point
// x:1
// y:2
displayPts(points);
Point 1: 1, 2
Point 2: 3, 5
Point 3: 2, 8
Point 4: 4, 4
1,2
3,5
2,8
4,4
12,-3
객체에 포함된 배열
//온도 입력기 & 평균
function weekTemps(){
this.dataStore = [];
this.add = add;
this.average = average;
}
function add(temp){
this.dataStore.push(temp);
}
function average(){
var total = 0;
for(var i=0; i<this.dataStore.length; i++){
total += this.dataStore[i];
}
return total / this.dataStore.length; //왜 reduce를 쓰지 않지?
}
var thisWeek = new weekTemps();
thisWeek.add(50);
thisWeek.add(52);
thisWeek.add(54);
console.log(thisWeek.average()); // 52