我有一个需要以下内容的项目。
代码中将声明四个数组,如下所示:
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]。
所以:
之前(根据配置的要求):
<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/