【问题标题】:Need to format an array of objects in a different way需要以不同的方式格式化对象数组
【发布时间】:2019-01-20 09:12:08
【问题描述】:

我有一个矩阵响应数组:

matrixArray = [
                {Responded: 1, RowName: row1, ColName: col1},
                {Responded: 2, RowName: row1, ColName: col2},
                {Responded: 0, RowName: row1, ColName: col3},
                {Responded: 0, RowName: row2, ColName: col1},
                {Responded: 0, RowName: row2, ColName: col2},
                {Responded: 1, RowName: row2, ColName: col3},
                {Responded: 1, RowName: row3, ColName: col1},
                {Responded: 0, RowName: row3, ColName: col2},
                {Responded: 1, RowName: row3, ColName: col3},
                ...
                ...
              ];

它告诉某列已经响应了多少次一行。 我需要以下格式的对象数组:

matrixArray = [
                {
                  RowName: row1,
                  col1: 1,           //Here '1' is no. of times column responded
                  col2: 2,
                  col3: 0
                },
                {
                  RowName: row2,
                  col1: 0,
                  col2: 0,
                  col3: 1
                },
                {
                  RowName: row3,
                  col1: 1,
                  col2: 0,
                  col3: 1
                },
              ];

我为此使用 TypeScript。 谢谢。

【问题讨论】:

  • 请分享您的尝试。
  • 您可以编辑您的问题。另外,正如我上面所说,你应该在人们帮助你之前展示你尝试过的东西。至少分享一下你的方法是什么,以及你想不通的地方。
  • 我已经准备好了答案,无论如何我都会在我忘记它之前发布它。下次请努力展示你的尝试。
  • 道歉@Jeto,但有一些连接问题,所以无法发布我的尝试。我在数组上使用了 forEach 和 .filter 。我的计划是首先在不同的数组中获取行,然后将相应的列推送到它。但这个计划实际上并没有奏效。

标签: javascript arrays typescript object


【解决方案1】:

你可以利用Array.reduceObject.values来获得想要的结果:

const matrixArray = [
  {Responded: 1, RowName: 'row1', ColName: 'col1'},
  {Responded: 2, RowName: 'row1', ColName: 'col2'},
  {Responded: 0, RowName: 'row1', ColName: 'col3'},
  {Responded: 0, RowName: 'row2', ColName: 'col1'},
  {Responded: 0, RowName: 'row2', ColName: 'col2'},
  {Responded: 1, RowName: 'row2', ColName: 'col3'},
  {Responded: 1, RowName: 'row3', ColName: 'col1'},
  {Responded: 0, RowName: 'row3', ColName: 'col2'},
  {Responded: 1, RowName: 'row3', ColName: 'col3'}
];

const result = Object.values(matrixArray.reduce((result, entry) => {
  if (!(entry.RowName in result)) {
    result[entry.RowName] = {RowName: entry.RowName};
  }
  if (!(entry.ColName in result[entry.RowName])) {
    result[entry.RowName][entry.ColName] = 0;
  }
  result[entry.RowName][entry.ColName] += entry.Responded;
  return result;
}, {}));

console.log(result);

请注意,我没有在此处键入变量以使其可运行,因为您使用的是 Typescript,请随意这样做。

解释:

  • Array.reduce 循环遍历数组并通过在每次迭代中增加相应的 Responded 数量来构建 RowName => {RowName, col1, col2, col3} 映射(对象),
  • Object.values 然后将其转换回数组。

【讨论】:

    【解决方案2】:

    您可以像这样使用reduceObject.values

    const matrixArray = [{Responded:1,RowName:'row1',ColName:'col1'},{Responded:2,RowName:'row1',ColName:'col2'},{Responded:0,RowName:'row1',ColName:'col3'},{Responded:0,RowName:'row2',ColName:'col1'},{Responded:0,RowName:'row2',ColName:'col2'},{Responded:1,RowName:'row2',ColName:'col3'},{Responded:1,RowName:'row3',ColName:'col1'},{Responded:0,RowName:'row3',ColName:'col2'},{Responded:1,RowName:'row3',ColName:'col3'}]
    
    const merged = matrixArray.reduce((acc, {Responded,RowName,ColName}) => {
           acc[RowName] = acc[RowName] || {RowName};
           acc[RowName][ColName] = (acc[RowName][ColName] + Responded) || Responded;
           return acc;
       }, {});
    
    const output = Object.values(merged);
    console.log(output)

    以下是上述代码的简短版本:

    const matrix = [{Responded:1,RowName:'row1',ColName:'col1'},{Responded:2,RowName:'row1',ColName:'col2'},{Responded:0,RowName:'row1',ColName:'col3'},{Responded:0,RowName:'row2',ColName:'col1'},{Responded:0,RowName:'row2',ColName:'col2'},{Responded:1,RowName:'row2',ColName:'col3'},{Responded:1,RowName:'row3',ColName:'col1'},{Responded:0,RowName:'row3',ColName:'col2'},{Responded:1,RowName:'row3',ColName:'col3'}],
      
    output = Object.values(matrix.reduce((a, {Responded,RowName,ColName}) => (
        (a[RowName] = a[RowName] || {RowName})[ColName] = Responded, a), {}));
    
    console.log(output);

    【讨论】:

    • @Mr.A 提醒一下:接受的答案在reduce 中硬编码了列名。如果有另一个名为 col4 的列,它将不起作用。
    • @adiga 已修复——我确实认为这些列是特定的。需要注意的是,如果多个条目具有相同的 RowName / ColName(在这种情况下,每次增加 Responded 计数是合乎逻辑的),则此条目效果不佳。不确定这是可能的(可能不是!)
    • @Jeto 是的,我必须在两者之间添加一个三元组来处理这个问题。查看 OP 的数据,我认为行和列不会有任何重复。
    猜你喜欢
    • 2016-04-23
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 2022-11-01
    • 1970-01-01
    • 2020-07-07
    相关资源
    最近更新 更多