July 26th 2018
안녕하세요.
현재 Array methods를 학습하고 있는데, 몇몇 method가 비슷한 부분도 있고 헷갈리기도 해서 한 번 정리하고 넘어가고자 합니다. 이번 포스팅에서는 아래의 Array methods에 관해서 요점만 간략히 정리하고자 합니다. sort method는 헷갈려서 조금 더 자세히 살펴 보았습니다.
Array methods
1. Concat Summary - argument로 주어진 배열이나 값을 기존 배열에 합쳐 새로운 배열을 반환함. - immutable => return 값으로 새 배열을 반환함. - Syntax : arr.concat(value1 [, value2 [, valueN]]);
// concat 예시
var num1 = [1, 2, 3];
var num2 = [4, 5, 6];
var str1 = ['a', 'b', 'c'];
var str2 = 'another string';
var newArr = num1.concat(num2, str1, str2);
console.log(newArr);
// result : [1, 2, 3, 4, 5, 6, "a", "b", "c", "another string"]
2. Every Summary - 배열의 모든 요소를 argument로 주어진 callback 조건에 부합하는지 boolean값을 반환함. - immutable (기존 배열을 변화시키지 않음) - Syntax : arr.every(callback [, thisArg])
// Every 예시
function isBigEnough(element, index, array) {
return element >= 10;
}
var arr1 = [12, 5, 8, 130, 44];
var arr2 = [12, 54, 18, 130, 44];
arr1.every(isBigEnough); // false
arr2.every(isBigEnough); // true
3. Some Summary - 위의 Every method와 기능이 비슷함. - 차이점은 배열의 한 요소만 Test에 통과해도 true 값을 반환함. - immutable (기존 배열을 변화시키지 않음) - Syntax : arr.some(callback [, thisArg])
// Some 예시
function isBigEnough(element, index, array) {
return element >= 10;
}
var arr1 = [12, 5, 8, 130, 44];
var arr2 = [12, 54, 18, 130, 44];
arr1.some(isBigEnough); // true
arr2.some(isBigEnough); // true
4. Fill Summary - fill method는 start index부터 end index까지 정해진 값으로 채움. - 차이점은 배열의 한 요소만 Test에 통과해도 true 값을 반환함. - mutable (기존 배열을 수정함.) - start 또는 end 값으로 음수가 오면 음수 + 배열.length 값으로 변환 - Syntax : arr.fill(value [, start[, end]])
// Fill 예시
[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
[1, 2, 3].fill(4, 3, 5); // [1, 2, 3]
Array(3).fill(4) // [4, 4, 4]
// 아래 두 구문은 잘 이해가 안 가서 다음에 다시 확인하고자 합니다. :)
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
/* Objects by reference*/
var arr = Array(3).fill({}) // [{}, {}, {}];
arr[0].hi = "hi"; // [{ hi: "hi" }, { hi: "hi" }, { hi: "hi" }]
5. Reverse Summary - 배열의 순서를 반전시킵니다. - mutable (기존 배열을 변화시킴) - 기존 배열을 변형 후 배열의 참조를 반환함. - Syntax : arr.reverse();
// reverse 예시
var newArr = ['one', 'two', 'three', 'four'];
newArr.reverse();
console.log(newArr); // ["four", "three", "two", "one"]
6. Sort sort는 다른 method보다 조금 복잡하게 느껴져, 익숙해 지기 위해 연습이 좀 더 필요할 것 같습니다. Summary - 배열 요소의 순서를 변경 후 해당 배열을 반환함. (mutable) - parameter로 compareFunction을 받음. - compareFunction 생략 시 글자열 default 값으로 정렬 (Unicode code point value에 따라 정렬됨.) - Syntax : arr.sort([compareFunction])
// sort 예시 - 배열이 number인 경우
var values_1 = [5, 4, 9, 2, 1];
consoel.log(values_1); // [5, 4, 9, 2, 1]
values.sort();
console.log(values_1); // [1, 2, 4, 5, 9]
var values_2 = [5, 4, 9, 2, 10, 1];
values_2.sort();
console.log(values_2); // [1, 10, 2, 4, 5, 9]
이와 같이 sort method로 argument를 넣지 않고, element가 number인 배열을 sorting 하면, 낮은 수에서 큰 수로 배열이 정리됩니다. 하지만, 배열 요소 중 10이 있으면 1 다음에 위치하게 됩니다. 이는 기본 정렬 순서가 Unicode point에 따르기 때문입니다.
배열 요소가 String인 경우에는 어떨까요?
// sort 예시 - 배열이 string인 경우
var values = ['a', 'hello', 'world', 'b', 'goodluck'];
console.log(values); // ["a", "hello", "world", "b", "goodluck"]
values.sort();
console.log(values); // ["a", "b", "goodluck", "hello", "world"]
배열 요소에 대문자와 소문자 String이 함께 있으면 대문자가 배열 앞쪽에 위치합니다.
// sort 예시 - 배열이 소문자, 대문자 string인 경우
var values = ['a', 'hello', 'world', 'B', 'goodluck'];
console.log(values); // ["a", "hello", "world", "B", "goodluck"]
values.sort();
console.log(values); // ["B", "a", "goodluck", "hello", "world"]
그리고, 배열에 number와 string이 함께 있으면, number가 숫자 순서로 먼저 정렬된 후, string이 alphabetical 순서로 정리됩니다.
// sort 예시 - 배열이 숫자, 소문자, 대문자 string인 경우
var values = ['a', 5, 'B', 2];
console.log(values); // ["a", 5, "B", 2]
values.sort();
console.log(values); // [2, 5, "B", "a"]
알파벳의 대소문자 구별 없이 또는 숫자의 크기대로 입맛에 맞게, 배열을 정리하려면 어떻게 해야 할까요? 이를 위해서는 comparing function을 별도로 작성해서 sort method에 인자로 전달 해야 합니다.
sort( ) - Comparing Function Compare function의 반환값에 따라 배열이 정리됩니다. a와 b가 배열 내의 비교되는 두 요소라고 한다면, 아래와 같은 기준으로 요소들이 정리됩니다.
-compareFunction(a, b)의 값이 0보다 작으면, a가 b보다 낮은 수의 인덱스 값을 가짐. -compareFunction(a, b)의 값이 0인 경우, 서로에 대해서는 순서가 변하지 않고 다른 모든 요소들에 대해 정렬됨. (note: 모든 브라우저에서 보장하지는 않음.) -compareFunction(a, b)의 값이 0보다 크면, b가 a보다 낮은 수의 인덱스 값을 가짐. 위와 같은 기준을 참고하여 compare function을 작성을 하면, 아래와 같인 함수를 만들 수 있습니다.
function compare(a, b) {
if(a is less than b by some ordering criterion ) {
return -1;
}
if(a is greater than b by the ordering criterion) {
return 1;
}
// a must be equal to b
return 0;
}
숫자인 배열의 요소를 단순히 오름차순으로 정렬하고자 할 때에는, 아래와 같이 함수의 반환값으로 a - b가 오면 숫자인 배열이 정렬됩니다.
var numbers = [4, 2, 5, 10, 7, 1];
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers); // => [1, 2, 4, 5, 7, 10]
객체의 경우 속성의 값을 Compare Function의 인자로 전달해, 정렬을 할 수 있습니다.
var people = [
{ name: 'Edward', age: 45 },
{ name: 'Kang', age: 38 },
{ name: 'Chan', age: 23 },
{ name: 'Woo', age: 33 },
{ name: 'Kim', age: 30 }
];
// age순 오름차순으로 정렬
people.sort(function(a, b) {
return a.age - b.age;
});
// 이름의 알파벳 순으로 정렬
people.sort(function(a, b) {
var nameA = a.name.toUpperCase(); // 대소문자 구분을 하지 않기 위해.
var nameB = b.name.toUpperCase();
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});