코딩을 하다보면 본인이 정의한 구조체의 요소를 기준으로 정렬하고 싶은 상황이 발생한다.
이때 sort.Interface 방식을 사용할 수 있다.
type StockInfo struct {
Name string `gorm:"column:item_name"`
Price string `gorm:"column:current_price"` // 현재가
PDE string `gorm:"column:then_yesterday"` // 전일비
TV string `gorm:"column:trading_volume"` // 거래량
MC string `gorm:"column:market_cap"` // 시가총액
}
예전에 크롤링한 주식 데이터를 예시로 들어보겠다.
func GetStockInfo() []*StockInfo {
SI := []*StockInfo{}
if err := DB.Limit(10).Find(&SI).Error; err != nil {
log.Println(err)
}
return SI
}
[{KODEX200선물인버스2X 2,550 40 +1.59% 81,327,851 17,409} {롯데손해보험 3,105 715 +29.92% 78,049,315 9,636}
{KTcs 4,420 0 0.00% 65,682,170 1,887}
{KODEX코스닥150선물인버스 3,745 25 +0.67% 34,932,963 8,464} {두산에너빌리티 17,900 880 +5.17% 16,985,221 114,660}
{KODEX인버스 4,550 40 +0.89% 14,325,993 7,335}
{KODEX코스닥150레버리지 11,575 145 -1.24% 12,063,843 8,045} {삼성전자 69,800 400 -0.57% 11,683,429 4,166,908}
{KODEX레버리지 16,670 275 -1.62% 9,840,847 18,220}
{한국무브넥스 7,050 580 +8.96% 9,686,257 2,147}
gorm을 이용해 슬라이스 형태로 데이터를 가져왔다.
func (x byStocks) Len() int { return len(x) }
func (x byStocks) Less(i, j int) bool {
myi, _ := strconv.Atoi(strings.ReplaceAll(x[i].Price, ",", ""))
myj, _ := strconv.Atoi(strings.ReplaceAll(x[j].Price, ",", ""))
return myi < myj
}
func (x byStocks) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
Len, Less, Swap 메소드를 가지는 슬라이스 타입을 정의한다.
func main() {
mysql.Connect()
stocks := mysql.GetStockInfo()
sort.Sort(byStocks(stocks))
printStocks(stocks)
}
sort.Sort 함수에 미리 정의한 슬라이스 타입으로 감싸 넘겨주면 끝이다.
정렬하기 전의 데이터와 한번 비교해 보자.
정렬하기 전
Name Price PDE TV MC
------ ------ ------ ------ ------
KODEX200선물인버스2X 2,550 40 81,327,851 17,409
롯데손해보험 3,105 715 78,049,315 9,636
KTcs 4,420 0 65,682,170 1,887
KODEX코스닥150선물인버스 3,745 25 34,932,963 8,464
두산에너빌리티 17,900 880 16,985,221 114,660
KODEX인버스 4,550 40 14,325,993 7,335
KODEX코스닥150레버리지 11,575 145 12,063,843 8,045
삼성전자 69,800 400 11,683,429 4,166,908
KODEX레버리지 16,670 275 9,840,847 18,220
한국무브넥스 7,050 580 9,686,257 2,147
정렬한 후
Name Price PDE TV MC
------ ------ ------ ------ ------
KODEX200선물인버스2X 2,550 40 81,327,851 17,409
롯데손해보험 3,105 715 78,049,315 9,636
KODEX코스닥150선물인버스 3,745 25 34,932,963 8,464
KTcs 4,420 0 65,682,170 1,887
KODEX인버스 4,550 40 14,325,993 7,335
한국무브넥스 7,050 580 9,686,257 2,147
KODEX코스닥150레버리지 11,575 145 12,063,843 8,045
두산에너빌리티 17,900 880 16,985,221 114,660
삼성전자 69,800 400 11,683,429 4,166,908
이와 같이 Price 요소를 중심으로 정렬된 것이 보인다.
func (x byStocks) Less(i, j int) bool {
myi, _ := strconv.Atoi(strings.ReplaceAll(x[i].TV, ",", ""))
myj, _ := strconv.Atoi(strings.ReplaceAll(x[j].TV, ",", ""))
return myi < myj
}
슬라이스 타입의 Less 함수에서 비교 대상이 되는 요소를 바꾸어 주면 된다.
Name Price PDE TV MC
------ ------ ------ ------ ------
한국무브넥스 7,050 580 9,686,257 2,147
KODEX레버리지 16,670 275 9,840,847 18,220
삼성전자 69,800 400 11,683,429 4,166,908
KODEX코스닥150레버리지 11,575 145 12,063,843 8,045
KODEX인버스 4,550 40 14,325,993 7,335
두산에너빌리티 17,900 880 16,985,221 114,660
KODEX코스닥150선물인버스 3,745 25 34,932,963 8,464
KTcs 4,420 0 65,682,170 1,887
롯데손해보험 3,105 715 78,049,315 9,636
## KODEX200선물인버스2X 2,550 40 81,327,851 17,409
func main() {
mysql.Connect()
stocks := mysql.GetStockInfo()
sort.Sort(sort.Reverse(byStocks(stocks)))
printStocks(stocks)
}
sort.Sort에 넘겨줄 때 sort.Reverse로 감싸주면 된다.
Name Price PDE TV MC
------ ------ ------ ------ ------
삼성전자 69,800 400 11,683,429 4,166,908
두산에너빌리티 17,900 880 16,985,221 114,660
KODEX레버리지 16,670 275 9,840,847 18,220
KODEX코스닥150레버리지 11,575 145 12,063,843 8,045
한국무브넥스 7,050 580 9,686,257 2,147
KODEX인버스 4,550 40 14,325,993 7,335
KTcs 4,420 0 65,682,170 1,887
KODEX코스닥150선물인버스 3,745 25 34,932,963 8,464
롯데손해보험 3,105 715 78,049,315 9,636
KODEX200선물인버스2X 2,550 40 81,327,851 17,409
References: The Go Programming Language (by Alan Donovan (Author), Brian Kernighan (Author))