ABOUT ME

노베이스 비전공자의 개발자 도전기

Today
Yesterday
Total
  • LexoRank에 대하여****
    TIL (Today I Learned) 2024. 1. 10. 23:48

      # LexoRank.....                                                                                                   

    최종프로젝트를 앞두고 TRELLO와 같은 칸반보드 백엔드 프로젝트를 담당하게 되어, 보드에서 생성된 칼럼과 카드를 드래그하여 이동할 수 있는 기능을 구현하는 업무를 맡게 되었습니다.
     
    프로젝트 진행 방향을 정할 때, [Before, Next] 방식으로 각 칼럼과 카드의 위치를 기억하고 지정하여 적용할지, 혹은 [LexoRank] 모듈을 활용할지에 대한 선택이 필요했습니다. 처음에는 전자의 방식을 선택하여 구현해보려고 했지만, 갑자기 [LexoRank] 방법을 시도해보고 싶어서 변경하게 되었습니다. 문제는 공식 문서와 여러 블로그를 찾아봐도 적용 예시에 대한 글이 부족하여 멘탈이 잠시 나갔지만 같은 조원인 조장님의 도움으로 로직을 쉽게 배울 수 있었습니다.
     


      # LexoRank란?                                                                                                             

    LexoRank 렉시코그래픽을 기반 알고리즘인데 무슨소린지 몰라서 찾아보니 사전순서를 기반으로 하는 랭킹 알고리즘이라고 합니다. 그래서 LexoRank를 이용하면 각 항목에 순서를 나타내거나 랭킹을 매기는데 주로 사용된다고 합니다. 
     
    예를 들면 "a", "b", "c", "d", "e" 이런 식으로 흘러가는 문자열은 렉시코그래픽이 적용된 예시로 볼 수 있습니다. 여기에 추가적인 기능으로 내가 "c"를 제일 위로 보내고 "a"를 끝으로 보내야지! 하면 그걸 가능하게 해주는게  Lexorank 입니다. 쉬게 말하면 랭킹 업데이트를 지원해주는 기능입니다. 그리고  추가적으로 칼럼 혹은카드를 삽입하거나 이동할 때 랭킹을 크게 변하게 하지 않도록 한다고 합니다. 
     
    밑의 사진을 보면 더 쉽게 이해하실 수 있을 것 같습니다. ㅎㅎㅎㅎㅎ 아래의 사진처럼 순서를 바꿀 수 있고 옆의 칼럼으로 넘어갈 수 있는 것을 구현할 수 있게 해주는 것이 Lexorank 알고리즘 입니다. 

     
    그래서 Lexorank 알고리즘은 간단하면서 효율적이고 고유한 랭킹 부여로 인해 중복된 랭킹 없이 목록의 순서를 유지할 수 있다고 합니다. 또한 중간에 아이템을 삽입하거나 이동시킬 때 유용합니다.


    # 테스트한 lexorank 로직

    import { Injectable } from '@nestjs/common';
    import { LexoRank } from 'lexorank';
    
    @Injectable()
    export class AppService {
      insert(_data: string) {
        throw new Error('Method not implemented.');
      }
      items: { data: string; lexo: LexoRank }[] = [
        { data: 'item1', lexo: null },
        { data: 'item2', lexo: null },
        { data: 'item3', lexo: null },
        { data: 'item4', lexo: null },
        { data: 'item5', lexo: null },
        { data: 'item6', lexo: null },
        { data: 'item7', lexo: null },
      ];
    
      constructor() {
        let lexoRank = LexoRank.middle();
        this.items.map((item) => {
          item.lexo = lexoRank;
          lexoRank = lexoRank.genPrev();
        });
      }
    
      //! lexo 값 출력
      find() {
        const newItems = this.items
          .sort((a, b) => {
            return a.lexo.compareTo(b.lexo);
          })
          .map((item) => {
            return { data: item.data, lexo: item.lexo.toString() };
          });
    
        return newItems;
      }
    
      //! 위치 이동
      move(id: number, where: number) {
        let newLexo: LexoRank;
    
        if (where >= this.items.length) {
          newLexo = this.items[this.items.length - 1].lexo.genNext();
        } else if (where <= 0) {
          newLexo = this.items[0].lexo.genPrev();
        } else {
          newLexo = this.items[where].lexo.between(this.items[where + 1].lexo);
        }
    
        this.items[id].lexo = newLexo;
    
        return true;
      }
    }

    # 도움될만한 링크 공유 

    *** 렉소랭크 테스트

    https://github.com/gozneokhan/nestjs-lexorank-test

     

    GitHub - gozneokhan/nestjs-lexorank-test

    Contribute to gozneokhan/nestjs-lexorank-test development by creating an account on GitHub.

    github.com

     

    *** 대략적으로 개념 설명과 코드 작성 방법 설명해주는 포스팅글 
    https://github.com/acadea/lexorank/blob/master/Lexorank.js

     

    LexoRank — what are they and how to use them for efficient list sorting

    In this article, we will explain what LexoRank is and how we find them and how used them in our mobile app to effectively sort lists and…

    medium.com

    https://github.com/acadea/lexorank/blob/master/Lexorank.js


     

Designed by Tistory.