JavaScript Complex Array“Element Reduction” - 배열 요소를 기반으로 HTML 테이블 구축

StackOverflow https://stackoverflow.com/questions/1419811

문제

다음이 필요한 프로젝트가 있습니다.

4 개의 배열이 코드에서 다음과 같이 선언됩니다.

var ROW1 = ['module1'];
var ROW2 = ['module2', 'module3'];
var ROW3 = ['module4', 'module5', 'module6'];
var ROW4 = ['module7', 'module8'];

이 배열의 각 요소는 구성 가능한 HTML 위젯의 모듈을 나타냅니다. 각 배열에 지정된 요소를 기반으로 코드는 이러한 "모듈"을 나타내는 HTML을 빌드합니다. 각 "rowx"배열은 테이블 행 ()이며 각 모듈은 테이블의 테이블 셀 ()이됩니다.

Row1은 비어 있거나 (이 경우 HTML에 포함되지 않음) 하나의 모듈 인 "Module1"이 있습니다.

Row2, Row3 및 Row4는 각각 0 내지 3 개의 모듈 (임의의 순서로 모듈 2 -module8)을 가질 수 있습니다.

위의 예제 배열을 사용하여 다음과 같은 HTML 테이블을 프로그래밍 방식으로 생성합니다.

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module2]</td>
    <td colspan="3">[module3]</td>
  </tr>
  <tr id="row3">
    <td colspan="2">[module4]</td>
    <td colspan="2">[module5]</td>
    <td colspan="2">[module6]</td>
  </tr>
  <tr id="row4">
    <td colspan="3">[module7]</td>
    <td colspan="3">[module8]</td>
  </tr>
</table>

(Colspans는 적절한 테이블 레이아웃을 보존하기 위해 단지 거기에 있습니다. 6은 1, 2 및 3 사이의 가장 낮은 일반적인 배수입니다.)

문제는 이러한 모듈의 내용이 동적으로 채워져 있다는 것입니다 (AJAX 호출에서 JSON 객체를 반환하는 URL로 가져옵니다). 모든 모듈에 대해 항상 콘텐츠를 사용할 수있는 것은 아닙니다. 콘텐츠가없는 모듈에 대한 빈 셀 ()을 만들기보다는 레이아웃에서 해당 셀을 완전히 제거하고 원래 구성에서는 없었던 것처럼 작용합니다 (즉, 배열의 배열).

이미 모듈 생성을 추상화하는 코드를 작성하는 데 많은 시간을 소비했습니다. 각 행에 몇 개의 모듈 수에 따라 "쉘"HTML 레이아웃을 생성 한 다음, 모듈이 어떤 모듈인지에 따라 적절한 테이블 셀에 컨텐츠를 추가합니다. 거기. 해당 코드를 계속 사용할 수 있기를 원 하므로이 작업을 수행하는 가장 좋은 방법은 "쉘"을 작성하기 전에 배열의 각 요소를 거치는 것입니다. 콘텐츠가없는 경우 해당 요소를 제거하십시오. 배열에서. 그런 다음 새로 수정 된 배열을 사용하여 평소 당 "쉘"을 빌드 할 수 있습니다. 기본적으로 각 모듈의 컨텐츠를 확인하기 위해 미리 처리하는 것만으로도 사용 가능한 경우 해당 모듈처럼 작용하는 것이 초기 배열에서 설정되지 않았습니다. (새 배열에서 제거한 다음이를 사용하여 "쉘"을 빌드함으로써).

예를 들어, 구성이 다음과 같이 설정되어 있다고 가정 해 봅시다.

var ROW1 = ['module1'];
var ROW2 = ['module4', 'module2'];
var ROW3 = ['module5'];
var ROW4 = ['module7', 'module3', 'module8'];

각 배열의 각 요소를 살펴보고 모듈에서 사용 가능한 콘텐츠를 확인하고 싶습니다. "module3"및 "module5"에 사용할 수있는 내용이 없다고 가정 해 봅시다. 그런 다음이 배열로 끝나고 싶습니다.

var ROW1 = ['module1'];
var ROW2 = ['module4', 'module2'];
var ROW3 = ['module7', 'module8'];

"module5"가 제거되었으므로 Rows에서 발생한 일에 주목하십시오. Row4 어레이의 요소가 Row3로 이동 한 다음 Row4를 삭제했습니다. 또한, 새로운 Row3 (이전의 Row4)에서 "module3"이 제거되었고, 위치 [2]에서 위치 [1]로 "module8"을 슬라이딩했습니다.

그래서:

  • 컨텐츠가없는 모듈을 제거한 후 하나 이상의 요소가 남아있는 행을 하나 이상의 모듈 만 있더라도 행을 그대로 유지하고 싶습니다.
  • 남은 요소가없는 행에있는 경우, 각 연속 행을 "Up"One을 이전 배열로 옮기고 기본적으로 행을 꺼내고 하단을 위로 이동하려고합니다. 이 예제의 HTML은 다음과 같습니다.

이전 (구성에 의해 요청 된대로) :

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module4]</td>
    <td colspan="3">[module2]</td>
  </tr>
  <tr id="row3">
    <td colspan="6">[module5]</td>
  </tr>
  <tr id="row4">
    <td colspan="2">[module7]</td>
    <td colspan="2">[module3]</td>
    <td colspan="2">[module8]</td>
  </tr>
</table>

후 (실제로 사용 가능한 콘텐츠에 따라)

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module4]</td>
    <td colspan="3">[module2]</td>
  </tr>
  <tr id="row3">
    <td colspan="3">[module7]</td>
    <td colspan="3">[module8]</td>
  </tr>
</table>

Row1은 다른 행에 영향을 미치지 않는다는 점에서 특별한 경우라는 것을 상기하십시오. "module1"(ROW1에서 사용할 수있는 유일한 모듈)에 컨텐츠를 사용할 수있는 경우 Row1이 손대지 않아야합니다. 콘텐츠를 사용할 수없는 경우 Row1을 삭제할 수 있지만 여전히 Row2, Row3 및 Row4를 남겨 두십시오 (즉, 각각 행을 이동하지 않음). Row1의 논리는 매우 간단하기 때문에 Row2, Row3 및 Row4를 처리하기위한 솔루션 만 있으면됩니다.

저는 초보자/중급 JavaScript 프로그래머이며 배열에 대한 경험이 많지 않습니다. 나는 이것을 몇 시간 동안 켜고 끄고 노력해 왔지만, 내가 다가오는 것이 강력하거나 우아한/컴팩트 한 방법이라고 생각하지 않습니다.

JavaScript Gurus가이를위한 솔루션을 공유 할 수 있다면 대단히 감사하겠습니다! 무리 감사.

도움이 되었습니까?

해결책

우선, 행을 배열에 저장하십시오. Row1 -Row4는 두통을 줄 것입니다.

var ROWS = [
 ['module1'],
 ['module4', 'module2'],
 ['module5'],
 ['module7', 'module3', 'module8']
];

또한 요소를 제거하는 방법을 원합니다. .splice() 배열에 내장되어 있으며 요소를 제거하는 데 적합합니다.

// lets clear out our disabled modules

var disabledModules = ['module3', 'module5'];

// quick sample function - yours might check for empty content or whatever else...
function isDisabled(module) {  
  for (var i=0, test; test=disabledModules[i]; i++) {
    if (test === module) return true;
  }
  return false;
}

for(var i=0,row; row=ROWS[i]; i++) {
  for (var j=0,module; module=row[j]; j++) {
    // is this module in our disabled modules list?

    if (isDisabled(module)) { // the module is disabled
      row.splice(j,1);
      j--; // so we recheck this point in the array
    }
  }
  if (row.length < 1) {
    // all items were deleted
    ROWS.splice(i,1);
    i--; // so we recheck this point..
  }
}

// ROWS === [["module1"], ["module4", "module2"], ["module7", "module8"]]

귀하의 의견은 사용 된 For Loop Syntax에 대해 물었습니다. "거짓"값이 없다는 것을 알고있는 배열을 통해 반복하는 매우 빠른 방법입니다. 하나를 분리하고 장방 로깅을 켜기 :

 for(
  // Part 1 of for loop: Setup, create two variables, i=0, and row.
  var i=0,row; 
  // Part 2: The test - when false, loop will exit, gets executed pre-loop every time
  // Assignment operator returns the value assigned, so row=ROWS[i] will be undefined
  // (false) when we reach then end of the array.
  row=ROWS[i]; 
  // Part 3: Post loop - increment i
  i++) {

그러나이 방법을 사용하는 위험은 예를 들어 숫자의 배열이고 해당 숫자 중 하나가 0이면 루프가 일찍 종료됩니다. 대안은 다음과 같습니다.

for(var i=0; i<ROWS.length; i++) { 
  var row = ROWS[i];
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top