首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >插入数组对象的中间/第一个后更改数组对象的键

插入数组对象的中间/第一个后更改数组对象的键
EN

Stack Overflow用户
提问于 2020-10-14 13:35:47
回答 2查看 318关注 0票数 3

我正在处理一个类似Excel的应用程序,但是我在多维数组上遇到了问题。

我有一系列的列,如下所示:

代码语言:javascript
复制
var columns = [
  {A: {binding: "A",header: "A"},
  {B: {binding: "B",header: "B"},
  {C: {binding: "C",header: "C"}
];

然后,我有一个数组,表示每个单元格的值,如下所示:

代码语言:javascript
复制
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之间新建一列。结果如下:

代码语言:javascript
复制
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,等等)。

我希望结果是这样的:

代码语言:javascript
复制
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行时,我会关注性能问题。

我有两个问题:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-14 15:13:29

首先,我认为Andam对这个问题的评论是正确的。当然,有更好的方法从对象数组中生成类似电子表格的显示。我的想法只是维护一个标头对象数组,其中包含(至少)列标题和要在列中显示的属性的名称。然后插入列只需更新该数组(并可能默认行的属性值)。

但是,您仍然希望按照您的问题所建议的方式进行,下面是一个可能的实现:

代码语言:javascript
复制
// 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))
代码语言:javascript
复制
.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.

重新构建对象,从而更改每一行。

在这里,我们传递给它一个虚拟列创建函数,我们可以注意到,它传递的是行对象、行索引和新的列索引。

我不知道它将如何表现你的真实数据,但你所描述的数字不会让我担心太多。这里可以做一些小的优化。例如,我们不需要重新计算每一行的列名,而是可以缓存它们。但只有当演出不符合你的期望时,我才会为他们操心。

而且,我再一次认为,有更好的方法来解决可能的潜在问题。

票数 2
EN

Stack Overflow用户

发布于 2020-10-14 14:22:37

行或列不要使用文字名称。

为了提高性能,直接将一个数据对象链接到列和/或行(在单元格数组中创建一些属性,如_row和_col ),并将_cells放在行和cols中。

示例:

代码语言:javascript
复制
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排序的单元格。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64354523

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档