我正在处理一个类似Excel的应用程序,但是我在多维数组上遇到了问题。
我有一系列的列,如下所示:
var columns = [
{A: {binding: "A",header: "A"},
{B: {binding: "B",header: "B"},
{C: {binding: "C",header: "C"}
];然后,我有一个数组,表示每个单元格的值,如下所示:
var data = [
{A:"row 0 col A", B: "row 0 col B", C:"row 0 col C"},
{A:"row 1 col A", B: "row 1 col B", C:"row 1 col C"},
{A:"row 2 col A", B: "row 2 col B", C:"row 2 col C"}
];binding数组中对象的columns属性将用于获取每一行的列的值。
但是,当在一些字母键的中间插入一个新列时,我遇到了一个问题。假设我需要在列A和列B之间新建一列。结果如下:
var columns = [
{A: {binding: "A",header: "A"},
{B: {binding: "B",header: "B"},
{C: {binding: "C",header: "C"},
{D: {binding: "D",header: "D"}
];它只是将新列推到columns上。
我认为必须在每一行的所有字母键之间插入一个新的单元格/项,并将所有键重命名(在本例中,将键B重命名为C,将C重命名为D,等等)。
我希望结果是这样的:
var data = [
{A:"row 0 col A", B:"new col inserted here", C:"row 0 col B", D:"row 0 col C"},
{A:"row 1 col A", B:"new col inserted here", C:"row 1 col B", D:"row 1 col C"},
{A:"row 2 col A", B:"new col inserted here", C:"row 2 col B", D:"row 2 col C"}
];如果要重命名所有这些键,特别是当我有120列( and )和100行时,我会关注性能问题。
我有两个问题:
发布于 2020-10-14 15:13:29
首先,我认为Andam对这个问题的评论是正确的。当然,有更好的方法从对象数组中生成类似电子表格的显示。我的想法只是维护一个标头对象数组,其中包含(至少)列标题和要在列中显示的属性的名称。然后插入列只需更新该数组(并可能默认行的属性值)。
但是,您仍然希望按照您的问题所建议的方式进行,下面是一个可能的实现:
// Utility function
const alphaNum = (cs) => (n) =>
n < cs.length
? cs [n % cs.length]
: alphaNum (cs) (Math.floor(n / cs.length) - 1) + cs [n % cs.length]
// Helper function
const toColumnName = alphaNum ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' .split (''))
// Main function
const insertColumn = (index, data, makeVal) =>
data .map ((item, i, arr, vals = Object .values (item)) => Object.fromEntries ([
...vals .slice (0, index),
makeVal (item, i, index),
...vals .slice (index)
] .map ((item, i) => [toColumnName(i), item])))
// Dummy cell creation function
const createCell = (row, rowNbr, colNbr) =>
`new col inserted at row ${rowNbr} col ${colNbr}`
// Sample data
const data = [{A: 'row 0 col A', B: 'row 0 col B', C: 'row 0 col C'}, {A: 'row 1 col A', B: 'row 1 col B', C: 'row 1 col C'}, {A: 'row 2 col A', B: 'row 2 col B', C: 'row 2 col C'}]
// Demo
console .log (insertColumn (1, data, createCell)).as-console-wrapper {max-height: 100% !important; top: 0}
toColumnName简单地将(基于零的)索引转换为类似电子表格的列标识符('A'、'B'、'C'、. 'Z'、'AA'、'AB'、. 'AZ'、'BA'、'BB'、…'BZ'、. 'ZZ'、'AAA'、.)h 219f 220。alphaNum,使用
,它执行繁重的任务。
insertColumn是主要的功能。它接受插入列的(基于零的)索引、数据和用于创建单元格值的函数。它通过提取值,插入函数创建的新值,然后从新索引中映射回列名,然后用Object .fromEntries.重新构建对象,从而更改每一行。
在这里,我们传递给它一个虚拟列创建函数,我们可以注意到,它传递的是行对象、行索引和新的列索引。
我不知道它将如何表现你的真实数据,但你所描述的数字不会让我担心太多。这里可以做一些小的优化。例如,我们不需要重新计算每一行的列名,而是可以缓存它们。但只有当演出不符合你的期望时,我才会为他们操心。
而且,我再一次认为,有更好的方法来解决可能的潜在问题。
发布于 2020-10-14 14:22:37
行或列不要使用文字名称。
为了提高性能,直接将一个数据对象链接到列和/或行(在单元格数组中创建一些属性,如_row和_col ),并将_cells放在行和cols中。
示例:
var data = {};
data.rows = [
{idx: 'A', _cells: []},
{idx: 'B', _cells: []},
{idx: 'C', _cells: []}
]
data.cols = [
{idx: 'A', _cells: []},
{idx: 'B', _cells: []},
{idx: 'C', _cells: []}
]
data.cells = [];
function addCell( rowIdx, colIdx, value) {
var row = data.rows[rowIdx];
var col = data.cols[rowIdx];
var cell = {value: value, _row: row, _col: col};
data.cells.push(cell);
row._cells.push(cell);
col._cells.push(cell);
}
for(var r=0; r<3; r++)
for (var c=0;c<3; c++)
addCell(r,c,'row ' + r + ' col ' + String.fromCharCode(65 + c));
console.log(data);
所以..。您可以毫不费力地插入/删除/排序/重命名行。
可以毫不费力地从列中插入/删除/排序/重命名所有单元格。
如果顺序很重要,则可以“映射”按行/col排序的单元格。
https://stackoverflow.com/questions/64354523
复制相似问题