본문 바로가기

Programming/javascript

[javascript] class object를 원소로하는 array의 sort

우선 제가 현재 주력으로 사용하는 언어인 java의 자료구조는 내부의 원소들을 정렬할 때

원소의 특정 property만으로 정렬이 가능한데요,

(이는 관련해서 조만간 정리해야겠네요^^;)

쉽게 생각하자면

database의 특정 column을 이용하여 내림차순, 오름차순 하듯이 data정렬을 하는 것 입니다.


이는 javascript에서도 그대로 사용이 가능합니다.

우선 javascript 의 Array 는 sort 메소드를 제공합니다.

이는 보통의 문자열이나 숫자를 sort하는 데에 매우 고마운 메소드입니다.


일반적으로 이와 같이 사용할 수 있죠.

var a = [33, 4, 1111, 222];

a.sort(); >>>> 1111, 222, 33, 4

이를 javascript the definitive guide 5판에서는 알파벳순이라고 표기하고 있습니다.

(위와 같은 경우 모든 원소가 숫자이며,

 sort() 메소드는 내부적으로 저 숫자원소들을 문자열로 변환하는 작업이 수반된다고합니다.)


그런데 sort메소드의 parameter로 정렬하고자 하는 함수를 넣는다면 좀 신기한 일이 벌어집니다.

a.sort(function(a,b){return a-b;});  >>>> 4, 33, 222, 1111

함수에서는 a와 b라는 인자를 받아서 그 뺏셈한 값을 return합니다.


function의 parameter a, b는 배열내의 원소들의 앞과 뒤라고 보시면 되겠습니다.

중요한 것은 저 함수의 로직이겠죠?

sort 메소드에 들어가는 저 함수의 로직은 아래와 같이 작성하면 됩니다.

첫번째로 전달받은 인자가 두번째로 전달받은 인자보다 배열내에서 앞에 있어야 한다면 0보다 작은 수가 return되야합니다.

바꿔서 첫번째로 전달받은 인자가 두번째로 전달받은 인자보다 뒤에 있어야 한다면 0보다 큰 수가 return되야합니다.

만약 첫번째로 전달받은 인자와 두번째로 전달받은 인자의 앞뒤 순서에 대해 정의할 필요가 없다면 0이 return되면 됩니다.


뭔가 학창시절에 공부하던, 프로그래밍을 처음 배우던 그때의 그것. 그것이 생각나지 않으신가요?

그렇죠, 바로 compareTo() 와 같은 역할을 로직으로 구현해주면 됩니다.


자, 그럼 sort 메소드 자체에 대한 소개가 길었는데, 이러한 문자열이나 숫자가 아닌

object에 대해서는 어떻게 구현해야할까요??

javascript가 참 재밌는게 구현할 방법이 너무나도 많고 제약이 없다는 것입니다.

(그만큼 저같은 초보는 멘붕이 오기도 하지요 ㅠㅠ)


여러가지 방법이 존재합니다만,

compareTo()와 같은 기능을 하는 메소드는 반드시 객체화하려는 class에 만들어주어야 하기 때문에

저는 아래와 같이만 구현하였습니다.

Grade = function(id, name, grade){
    this.id = id;
    this.name = name;
    this.grade = grade;
    this.compareToById = function(other){ return this.id - other.id; }
    this.compareToByGrade = function(other){ return this.grade - other.grade; }
}
var gradeArr = new Array();
var gradeArr.push(new Grade(1234, '브래드피트', 90);
var gradeArr.push(new Grade(1235, '안젤리나졸리', 95);
var gradeArr.push(new Grade(1236, '톰행크스', 85);
var gradeArr.push(new Grade(1237, '엠마왓슨', 100);
gradeArr.sort(function(grade1, grade2){ return grade1.compareToByGrade(grade2);});
// 톰행크스 - 브래드피트 - 안젤리나졸리 - 엠마왓슨 순으로 정렬이 됩니다.
gradeArr.sort(function(grade1, grade2){ return grade1.compareToById(grade2);});
// 브래드피트 - 안젤리나졸리 - 톰행크스 - 엠마왓슨 순으로 정렬이 됩니다.

완벽하게 가이드해주는 자바스크립트 완벽가이드 5판(위에서 소개한 그것)에서는

객체를 가져다 쓰는 클라이언트 코드를 보다 더욱 간소화 하기 위해서

이와 같이 추가적인 방법을 소개합니다.

Grade = function(id, name, grade){
    this.id = id;
    this.name = name;
    this.grade = grade;
    this.compareToById = function(other){ return this.id - other.id; }
    this.compareToByGrade = function(other){ return this.grade - other.grade; }
    this.compareById = function(grade1, grade2){ return grade1.compareToById(grade2); };
    this.compareByGrade = function(grade1, grade2){ return grade1.compareToByGrade(grade2); };
}
var gradeArr = new Array();
var gradeArr.push(new Grade(1234, '브래드피트', 90);
var gradeArr.push(new Grade(1235, '안젤리나졸리', 95);
var gradeArr.push(new Grade(1236, '톰행크스', 85);
var gradeArr.push(new Grade(1237, '엠마왓슨', 100);
gradeArr.sort(function(grade1, grade2){ return grade1.compareToByGrade(grade2);});
gradeArr.sort(Grade.compareByGrade);
// 톰행크스 - 브래드피트 - 안젤리나졸리 - 엠마왓슨 순으로 정렬이 됩니다.
gradeArr.sort(Grade.compareById);
gradeArr.sort(function(grade1, grade2){ return grade1.compareToById(grade2);});
// 브래드피트 - 안젤리나졸리 - 톰행크스 - 엠마왓슨 순으로 정렬이 됩니다.


어떻게 보면 가이드에서 알려주는 그대로 비교구문은 비교구문대로,

정렬을 하는 메소드는 메소드대로 있음이 맞는 것 같습니다.

음.... 정리하고 나니 그게 맞는 코드인 것 같네요 -_-;;

아.... 코드 다시 수정해야겠군요 ㅎㅎ;;;;


위처럼 Class 의 메소드에 비교구문 메소드와 sort 메소드를 정의해놓으면

Class를 객체화 하고 이를 원소로 하는 배열을 쓸 때에는 정렬을 하기가 무척이나 용이합니다.


예전에는 view layer는 따로 프레임웤이 있거나 웹퍼블리셔분들이 계셔서

javascript에 대해 깊이 공부를 할 일이 없기도 하고 집에서 만드는 장난감들도 거의 server side에 집중하던터라

javascript를 깊이 못봤는데 보면 볼수록 참 매력적인 언어로 보입니다.

ㅎㅎ;;; 이것참 공부할게 무척 많군요 ㅎㅎㅎ ㅠㅠ


//추가

금일 Array 에 대해서 좀 살펴보는데 많이 본 메소드가 눈에 띄더군요.

concat();

이것은 javascript 문자열에서 쓰이는 메소드이기도 한 것으로

문자열에 어떤 값을 덧붙이고자 할 떄에 쓰입니다.

만약 숫자라면 내부적으로 문자열로 변환이되어서 문자열에 덧붙여지죠.

이때 특정 변수에 값을 받지 않더라도 주체가되는 문자열은 concat() 메소드로 붙여진 문자열이 덧붙여집니다.

+ 연산기호로 문자열과 문자열을 잇는 데에는 문제가 없습니다만,

(물론 연산기호를 사용하는 경우엔 그 결과를 받아야하는 변수가 있어야겠죠.)

숫자를 붙이게 되는 경우에는 종종 지원하지 않는 연산이나 메소드라는 오류메시지를 받게 되죠.

이럴때 유용하게 쓸 수 있는 것이 concat() 메소드입니다.

이것으로 미루어보았을때 다른 언어의 char 배열의 조합인 String 클래스가 생각나더군요.

그럼 혹시 javascript도 ``??

어쨌거나 javascript 에서 문자열은 배열로 저장이 되나 봅니다. :)