본문 바로가기

Javascript & Jquery

[Javascript] 재귀함수 실제 적용한 예제. 사용자가 입력한 여러 키워드를 조합하는 기능

재귀함수란?

자바스크립트 함수 안에서 다시 자신의 함수를 호출하면서 로직을 처리하는 경우를 말합니다. 일단 개념 자체는 아주 단순합니다. 

function recurcive(){
	...
    recurcive();
}    

 

 

어떤 경우에 사용했나?

아래와 같이 사용자가 입력한 여러 키워드를 조합해서 가능한 모든 경우의 수를 표시해야하는 경우가 있다고 합시다.

대략 어떤 기능인지 이해가 가시나요? 

 

<textarea>에 사용자가 엔터로 구분된 키워드를 입력하면 모든 경우의 수를 고려해서 키워드를 조합해서 보여주는 기능입니다. <textarea>는 1개가 될 수도 있고 5개가 될 수도 있기 때문에 자바스크립트  html의 textarea 태그와 무관하게 작동해야했습니다. 이런 경우 필요한게 자바스크립트의 재귀함수 였습니다. 

 

재귀함수를 사용하지 않을 경우 textarea의 키워드를 배열로 만들어서 for 문을 중첩해서 돌려야하죠. 

만약 textarea가 추가되거나 삭제된다면 자바스크립트의 함수도 같이 수정해야 하고요

 

 

실제 구현한 주요 로직

실제 구현한 로직을 보기 전에 지금 javascript를 공부하는 분이라면 '나라면 어떻게 구현할까?' 머리속으로 그려본 후에 구현로직을 보는 걸 추천드립니다. 

html 구조

<div>
  <textarea rows="5" cols="12" name="kwrdAnaly"></textarea>
  <textarea rows="5" cols="12" name="kwrdAnaly"></textarea>
  <textarea rows="5" cols="12" name="kwrdAnaly"></textarea>
  <textarea rows="5" cols="12" name="kwrdAnaly"></textarea>
  <textarea rows="5" cols="12" name="kwrdAnaly"></textarea>
</div>
<div class="float-right">
  <button type="button" id="kwrdMxtr">키워드 조합</button>
</div>  
<!--키워드 조합 결과 표시-->
<ol id="kwrdMxtrResult">
</ol> 

 

javascript

고려사항

<textarea> 의 개수는 고정되어 있지 않음. N개 일 수 있음. 

사용자가 textarea를 두번째부터 입력할 수도 있고, 1개만 입력할 수도 있으며, 중간은 비워놓을 수도 있음

(즉, 키워드 조합시 키워드 Validation을 체크해서 적절하게 조합해야 함)

$(document).ready(function(){
  $("#kwrdMxtr").click(function(){
    kwrdMxtr();
  });
});

//키워드 조합 후 화면에 표시하는 함수
function kwrdMxtr(){

  //사용자가 입력한 textarea의 객체를 가져옴
  var $kwrdAnalyArr = $("textarea[name='kwrdAnaly']");

  var firstKwrdAnalyArr;
  var pos = 1;

  //사용자가 첫번째 textarea에 값을 입력하지 않을 수 있으므로 
  //실제로 키워드가 입력된 textarea를 첫번째로 설정하는 로직이 추가됨.
  $kwrdAnalyArr.each(function(e){
    if($(this).val() != '' && !firstKwrdAnalyArr){
      firstKwrdAnalyArr = $(this).val().split("\n");
      return false;
    }else{
      pos++;
    } 
  });

  if(firstKwrdAnalyArr){
    var kwrdAnalyArr = getKwrdAnalyArr(firstKwrdAnalyArr, $kwrdAnalyArr, pos);

    $("#kwrdMxtrResult").html('');//기존에 표시되었던 조합키워드 삭제
    
    //조합키워드 표시
    for(i=0;i<kwrdAnalyArr.length; i++){
      $("#kwrdMxtrResult").append("<li>" + kwrdAnalyArr[i] + "</li>");
    }
  } 
}

//첫번째 textarea의 키워드와 다음 textarea에 있는 키워드들을 조합해서 리턴하는 함수
function getKwrdAnalyArr(firstKwrdAnalyArr, $kwrdAnalyArr, pos){

  //키워드를 조합할 두번째 textarea 값을 가져옴. 
  //말은 두번째라고 표현했지만 실제로 몇번째인지는 pos를 통해서 파악하게 됩니다.
  var secondKwrdAnalyVal = $kwrdAnalyArr.eq(pos).val();
  var secondKwrdAnalyArr = secondKwrdAnalyVal.split("\n");

  //첫번재와 두번째 키워드들을 조합해서 저장할 배열 객체
  var newKwrdAnalyArr = new Array();	

  //배열 중첩 for문을 통해 첫번째와 두번째 키워드를 결합해서 새로운 키워드 배열에 저장
  for (var i = 0; i < firstKwrdAnalyArr.length; i++) {

    if(secondKwrdAnalyArr.length > 0){

      for (var j = 0; j < secondKwrdAnalyArr.length; j++) {

        var firstKwrd = firstKwrdAnalyArr[i].trim();
        var secondKwrd = secondKwrdAnalyArr[j].trim();

        //첫번째와 두번재 키워드가 있는지를 체크해서 키워드 조합
        if(firstKwrd != '' && secondKwrd != ''){
          newKwrdAnalyArr.push(firstKwrd + " " + secondKwrd); 
        }else if(firstKwrd == '' &&  secondKwrd != ''){
          newKwrdAnalyArr.push(secondKwrd);
        }else if(firstKwrd != '' &&  secondKwrd == ''){
          newKwrdAnalyArr.push(firstKwrd);
        }				
      }

    }else{
      newKwrdAnalyArr.push(firstKwrdAnalyArr[i].trim());
    }
  }

  //만약 다음 textarea가 있을 경우 다시 getKwrdAnalyArr를 호출(재귀함수)
  if($kwrdAnalyArr.eq(pos + 1).length > 0){
    return getKwrdAnalyArr(newKwrdAnalyArr, $kwrdAnalyArr,  pos + 1);
  }else{
    return newKwrdAnalyArr;
  }

}

 

 

추가적으로 고려해야할 사항 때문에 로직이 좀 복잡해보이네요. ㅎㅎ

중요한 건 textarea의 개수가 가변적인 N개이고, 각 키워드들의 조합을 해야하기 때문에 '재귀함수' 라는 걸 이용해야 하는구나라고 생각하는 겁니다. 그리고 재귀함수의 인자를 어떻게 정할건지도 중요하고요. 

 

실제 중요한 로직만 분리해서 살펴보면 아래와 같습니다.

//첫번째 textarea의 키워드와 다음 textarea에 있는 키워드들을 조합해서 리턴하는 함수
function getKwrdAnalyArr(firstKwrdAnalyArr, $kwrdAnalyArr, pos){

  ....
  
  //만약 다음 textarea가 있을 경우 다시 getKwrdAnalyArr를 호출(재귀함수)
  if($kwrdAnalyArr.eq(pos + 1).length > 0){
    return getKwrdAnalyArr(newKwrdAnalyArr, $kwrdAnalyArr,  pos + 1);
  }else{
    return newKwrdAnalyArr;
  }

}

 

실제 웹사이트에 적용한 소스를 예제로 Javascript 재귀함수를 살펴봤습니다. 

다음에도 웹사이트 개발 중에 재미있는 Javascript 예제가 있으면 또 포스팅하도록 하겠습니다.