내일배움캠프 TIL

LexoRank 를 적용하여 카드 순서 이동하기 본캠프 TIL 01/31

parkcw0325 2025. 2. 1. 16:41

이번 트렐로 프로젝트에서 컬럼안에있는 카드들의 이동을 구현해야 했습니다.

카드들의 이동을 저장하기 위해서 처음에는

'카드 포지션이라는 컬럼을 이용하여 숫자를 지정해

해당 숫자를 기준으로 새롭게 재배열하는 식으로 로직을 작성하는 어떨까?'

라는 생각으로 숫자로 지정하였지만 이 방법은 숫자들이 반복적으로 가운데 값으로 지정되면 

결국 겹쳐지는 문제가 발생하였습니다

 

따라서 LexoRank 를 사용하였습니다.

 

LexoRank란?

LexoRank는 숫자가 아닌 문자열을 기반으로 정렬을 수행하는 방식입니다. 즉, 정렬 기준이 문자열로 이루어져 있습니다.

예를 들어, 다음과 같은 방식으로 중간 값을 생성할 수 있습니다.

  1. "hzzzzz"와 "hzzzzv" 사이의 값 → "hzzzzx"
  2. "hzzzzz"와 "hzzzzx" 사이의 값 → "hzzzzy"
  3. "hzzzzz"와 "hzzzzy" 사이의 값 → "hzzzzy:i"
    (알파벳 'z'와 'y' 사이에는 다른 문자가 없기 때문에 새로운 문자가 추가됩니다.)

만약 숫자로 정렬을 수행할 경우, 많은 연산이 이루어지면 부동소수점 오류 또는 횟수 제한과 같은 문제가 발생할 수 있습니다. 하지만 LexoRank는 문자열을 사용하기 때문에 훨씬 많은 연산이 가능하며, 소수점 문제도 발생하지 않습니다.

 

LexoRank의 주요 메서드

LexoRank를 활용하여 카드 삽입, 이동 등을 수행할 때 사용할 수 있는 주요 메서드는 다음과 같습니다.

  • LexoRank.toString()
    • LexoRank 값을 문자열 형태로 변환합니다.
  • LexoRank.middle()
    • LexoRank의 중간 값을 생성합니다. (초기 LexoRank 값을 설정할 때 사용됩니다.)
  • LexoRank.genNext()
    • 현재 LexoRank 값보다 큰 다음 LexoRank 값을 생성합니다.
  • LexoRank.genPrev()
    • 현재 LexoRank 값보다 작은 이전 LexoRank 값을 생성합니다.
  • LexoRank.between(other: LexoRank)
    • 두 LexoRank 값의 중간에 해당하는 LexoRank 값을 생성합니다.
  • LexoRank.compareTo(other: LexoRank)
    • 두 LexoRank 값을 비교한 결과를 반환합니다.

프로젝트 적용 전, 연습 코드

실제 프로젝트에 적용하기 전에, 간단한 추상 데이터를 활용하여 카드 이동 로직을 구현해 보았습니다.

카드 이동 시 필요한 로직은 다음과 같이 나눌 수 있습니다.

  1. 카드를 맨 처음 위치로 이동할 때
    • 첫 번째 위치한 카드의 LexoRank 값에서 genPrev()를 호출하여 더 작은 LexoRank 값을 할당합니다.
  2. 카드를 맨 끝 위치로 이동할 때
    • 마지막에 위치한 카드의 LexoRank 값에서 genNext()를 호출하여 더 큰 LexoRank 값을 할당합니다.
  3. 카드를 두 카드 사이로 이동할 때
    • between()을 호출하여 두 카드의 LexoRank 값 사이에 위치하는 새로운 LexoRank 값을 생성합니다.

이러한 방식으로 LexoRank를 활용하면 정렬된 순서를 유지하면서도 효율적으로 항목을 재배치할 수 있습니다.