我需要从一个一维数组构造一个 html 表,为了抽象起见,它具有以下格式:
{ value: "ABC", colspan: 1, rowspan: 2 }, // etc
还有一个名为 width 的属性,它将是动态的并表示列数。
我认为下面的代码很接近,并且可以处理“非行跨度”数据 - 但我对如何在表格不超过列数的情况下计算单元格跨越感到困惑。
我觉得我需要一个“步进器”,每当有一个行跨度时它就会向上和向下计数,但我无法正确计算。
此刻,任何rowspan都会导致下一行退出表格的右侧。
从本质上讲,我希望它能将每一个包裹起来并放到下一个可用的位置。换句话说,动态地组装表格。
http://jsbin.com/zopoxaqato/edit?js,console,output
const input = [
{ value: "a1", colspan: 1, rowspan: 1 },
{ value: "a2", colspan: 1, rowspan: 1 },
{ value: "a3", colspan: 1, rowspan: 3 },
{ value: "b1", colspan: 1, rowspan: 1 },
{ value: "b2", colspan: 1, rowspan: 1 },
{ value: "c1", colspan: 1, rowspan: 1 },
{ value: "c2", colspan: 1, rowspan: 2 },
{ value: "d1", colspan: 1, rowspan: 1 },
{ value: "d3", colspan: 1, rowspan: 1 },
{ value: "e1", colspan: 1, rowspan: 1 },
{ value: "e2", colspan: 2, rowspan: 1 },
];
const width = 3;
const trs = [];
let tds = [];
let rowSpanOffset = 0;
// Loops over entries
input.forEach((cell, index) => {
// Stock standard td
tds.push(`<td colspan="${cell.colspan}" rowspan="${cell.rowspan}">${cell.value}</td>`);
// New row time
if(index % width === width - 1 || rowSpanOffset < 0) {
trs.push("<tr>" + tds.join('') + "</tr>");
// Reset for next row
tds = [];
}
});
const leTable = "<table class='table'>"+trs.join('')+"</table>";
$("body").append(leTable);
http://jsbin.com/solesiyuro/edit?js,output
const input = [
{ value: "a1", colspan: 1, rowspan: 1 }, // 1
{ value: "a2", colspan: 1, rowspan: 1 }, // 2
{ value: "a3", colspan: 1, rowspan: 3 }, // 3
{ value: "b1", colspan: 1, rowspan: 1 }, // 1
{ value: "b2", colspan: 1, rowspan: 1 }, // 1
{ value: "c1", colspan: 1, rowspan: 1 }, // 1
{ value: "c2", colspan: 1, rowspan: 2 }, // 2
{ value: "d1", colspan: 1, rowspan: 1 }, // 1
{ value: "d3", colspan: 1, rowspan: 1 }, // 1
{ value: "e1", colspan: 1, rowspan: 1 }, // 1
{ value: "e2", colspan: 1, rowspan: 1 }, // 2
];
const width = 3;
const totalCellCount = _.reduce(input, (sum, c) => sum + c.colspan * c.rowspan, 0);
const grid = _.chunk(_.fill(new Array(totalCellCount), -1), width);
_.each(input, cell => {
let start = [-1, -1];
outerLoop:
for(let y = 0; y < grid.length; y++) {
for(let x = 0; x < width; x++) {
if(grid[y][x] === -1) {
start = [x, y];
break outerLoop;
}
}
}
for(let y = 0; y < cell.rowspan; y++) {
for(let x = 0; x < cell.colspan; x++) {
grid[start[1] + y][start[0] + x] = null;
}
}
grid[start[1]][start[0]] = cell;
});
let trs = [];
let tds = [];
for(let y = 0; y < grid.length; y++) {
for(let x = 0; x < grid[y].length; x++) {
const cell = grid[y][x];
if(cell) {
const value = cell.value;
tds.push('<td colspan="'+cell.colspan+'" rowspan="'+cell.rowspan+'">'+cell.value+'</td>');
}
}
trs.push('<tr>'+tds.join('')+'</tr>');
tds = [];
}
$(".table").append(trs.join(''));
错误输入的一个例子是拆分单元格:
const input = [
{ value: "a1", colspan: 1, rowspan: 1 },
{ value: "a2", colspan: 1, rowspan: 2 },
{ value: "a3", colspan: 1, rowspan: 1 },
{ value: "b1", colspan: 3, rowspan: 1 },
];
const width = 3;
最佳答案
我认为您的替代解决方案走在正确的轨道上,应该验证的两个极端情况是
width 时允许(蓝色单元格呈现出边界)我想出了以下算法,它与您的第二个解决方案非常相似
N 的矩阵行和 width列,N 的值将在需要时分配cell在你的输入中
i和 j是矩阵中第一个空位的行和列,那么我们需要占用下面的i + cell.rowspace次j + cell.colspace单元格,在实现中我使用单元格的索引cell试图占据一个越界的单元格抛出一个错误cell试图占据矩阵中已经保存了一些值的单元格抛出错误实现如下所示
class Matrix {
constructor(width) {
this.width = width
this.data = []
}
set(i, j, d) {
if (j >= width) throw Error(`set was run out of bounds index (${i}, ${j})`)
var value = this.get(i, j)
if (value !== undefined) throw Error(`cell (${i}, ${j}) is occupied with ${value}`)
this.data[i][j] = d
}
get(i, j) {
this.data[i] = this.data[i] || Array(this.width)
return this.data[i][j]
}
findNextEmpty(i, j) {
while (true) {
if (this.get(i, j) === undefined) {
return [i, j]
}
j += 1
if (j === this.width) {
i += 1
j = 0
}
}
}
fromData(data) {
let i = 0
let j = 0
data.forEach((meta, metaIndex) => {
[i, j] = this.findNextEmpty(i, j)
for (var ci = i; ci < i + meta.rowspan; ci += 1) {
for (var cj = j; cj < j + meta.colspan; cj += 1) {
this.set(ci, cj, metaIndex)
}
}
})
return this.data
}
}
try {
const table = new Matrix(width).fromData(input)
} catch (err) {
// the input was invalid
}
更新:用户在评论中发布了一个案例,该案例似乎无法正常呈现,上面的算法适用于此案例,甚至标记看起来也不错,但它看起来像是此表中的一行以等于零的高度呈现,我敢肯定有很多方法可以解决这个问题,我通过在 table tr 上设置固定高度来修复它元素
<tr> was rendered with a height = 0 关于javascript - 考虑到 rowspan 和 colspan,如何从一维数组创建动态 html 表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37189200/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta