Javascript复杂数组 "element reduction"- 基于数组元素构建HTML表格

标签 javascript html arrays loops html-table

我有一个需要以下内容的项目。

代码中将声明四个数组,如下所示:

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 - 模块 8 中的任何一个,以任何顺序)。

使用上面的示例数组,我将以编程方式生成一个 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>

(colspan 只是为了保持正确的表格布局;6 是 1、2 和 3 之间的最小公倍数。)

问题是,这些模块的内容是动态填充的(我从 AJAX 调用到返回 JSON 对象的 URL 获取它),并且内容并不总是可用于每个模块。我不想为没有内容的模块创建一个空单元格 (),而是想从布局中完全删除该单元格,就像它从未在原始配置中一样(即顶部的数组)。

我已经花了很多时间创建抽象模块创建的代码 - 它根据每行中有多少模块创建一个“shell”HTML布局,然后根据应该是哪个模块将内容附加到适当的表格单元格那里。我希望能够继续使用该代码,所以我认为最好的方法是在构建 "shell"之前遍历数组中的每个元素,如果我没有内容,请删除该元素从数组。然后我可以像往常一样使用新修改的数组来构建“shell”——我基本上只是事先处理它以检查每个模块中的内容,如果没有可用的内容,就像该模块从未设置在初始数组中一样(通过在新数组中删除它,然后使用它来构建“shell”)。

例如,假设配置是这样设置的:
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”被删除,ROW4 数组中的元素被移到 ROW3,然后 ROW4 被删除。此外,在新的 ROW3(以前的 ROW4)中,“module3”被移除,将“module8”从位置 [2] 滑动到位置 [1]。

所以:
  • 对于删除没有任何内容的模块后剩余一个或多个元素的任何行,我想保持该行完整,即使只有一个模块。
  • 对于最终没有剩余元素的任何行,我想将每个连续的行“向上”移动一个,进入前一个数组,基本上拉出一行并将较低的行向上移动。此示例中的 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 原样(即不将它们分别向上移动一行)。我真的只需要一个处理 ROW2、ROW3 和 ROW4 的解决方案,因为 ROW1 的逻辑非常简单。

    我是一名初学者/中级 JavaScript 程序员,对数组没有太多经验。我已经断断续续地研究了几个小时,但只是不觉得我想出的是一种健壮或优雅/紧凑的方法。

    如果任何 JavaScript 专家可以为此分享解决方案,我将非常感激!谢谢一堆。

    最佳答案

    首先,将您的行也存储在一个数组中,您的 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 循环语法。这是循环遍历您知道不会有“假”值的数组的一种非常快速的方法。拆开一个并打开详细日志记录:
     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];
    }
    

    关于Javascript复杂数组 "element reduction"- 基于数组元素构建HTML表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1419811/

    相关文章:

    C程序逐字符读取字符串

    arrays - 如果我将文件内容读入数组,是否需要初始化数组?

    javascript - 从 v8 中挤出性能

    javascript - 使用 jquery 类后退格键不起作用

    arrays - 从最低到最高对表格 View 单元格进行排序

    javascript - 如何根据 html 或 javascript 中的日期对列表进行排序?

    php - SoundCloud 如何让 favicon 在按下播放按钮时动态变化?

    javascript - 等待请求完成然后转到下一步

    javascript - 错误 TS2339 : Property 'Default' does not exist on type 'string' . **

    html - 位置 : fixed 的问题