将多个矩阵简化为单个矩阵并执行增值

时间:2018-09-15 13:38:02

标签: javascript dictionary matrix reduce

我在数据结构中有一个矩阵列表(数组),如下所示:

const data = [
  {
    matrix: {
      rows: {
        ROW1: {
          cols: {
            COL1: "4",
            COL2: "2"
          }
        },
        ROW2: {
          cols: {
            COL1: "1",
            COL2: "4"
          }
        },
        ROW3: {
          cols: {
            COL1: "2",
            COL2: "1"
          }
        }
      }
    },
  },
  {
    matrix: {
      rows: {
        ROW1: {
          cols: {
            COL1: "1",
            COL2: "6"
          }
        },
        ROW2: {
          cols: {
            COL1: "2",
            COL2: "3"
          }
        },
        ROW3: {
          cols: {
            COL1: "5",
            COL2: "2"
          }
        }
      }
    }
  }
];

我想对在相同的ROW:COL对上定义的值求和,并最终得到一个像这样的单个矩阵:

const newMatrix = {
  rows: {
    ROW1: {
      cols: {
        COL1: "5",
        COL2: "8"
      }
    },
    ROW2: {
      cols: {
        COL1: "3",
        COL2: "7"
      }
    },
    ROW3: {
      cols: {
        COL1: "7",
        COL2: "3"
      }
    }
  }
};

我事先不知道我可能在数据数组中接收多少个矩阵。我也事先不知道我会收到多少行和列。

我首先在数据上调用reduce(),但由于无法想到找到然后对具有相同名称的ROW:COL对进行汇总的方式而陷入困境。

const newMatrix = data.reduce(( accumulator, current ) => {
  let newMatrix;
  // ...???
  // find? forEach? Object.entries? for loops? maps inside maps? 
  // Everything I tried failed
  return newMatrix;
});

我也弄乱了forEach(),Object.values(),find()和其他循环内的各种for循环,但我自己却最终陷入某种大脑循环。

我意识到这可能还不足以解决问题,但是我是编程新手,不知道下一步该怎么做。

我已经在这个问题上停留了2.5天,所以即使没有提供直接的解决方案,我也希望在正确的方向上提供任何提示或指导。

不幸的是,我没有同行可以寻求帮助。

谢谢。

3 个答案:

答案 0 :(得分:0)

您必须反向执行此操作,这意味着要依次循环按列,行和矩阵。以下代码提供了详细的解决方案。

    function sumMatrices(data)
    {
        // if data empty or has missing fileds, return null
        if(
            !data || 
            !data[0].matrix.rows ||
            !data[0].matrix.rows.ROW1.cols ||
            data.length == 0 || 
            Object.keys(data[0].matrix.rows).length == 0 ||
            Object.keys(data[0].matrix.rows.ROW1.cols).length == 0)
        {
            return null; 
        }
    
        // else sum and return the result matrix
        else
        {
            // Get matrix, row, and column counts
            let numOfMatrices =  data.length;
            let numOfRows = Object.keys(data[0].matrix.rows).length;
            let numOfCols = Object.keys(data[0].matrix.rows.ROW1.cols).length;
    
            // Copy matrix structure 
            let result = JSON.parse(JSON.stringify(data[0]));
    
            // Fields base names to be addressed
            let rowWord = 'ROW';
            let colWord = 'COL';
    
            // Loop in reverse: columns -> rows -> matrices 
            for (colNum = 1; colNum < numOfCols+1; colNum++){
                let currentCol = colWord + colNum;

                for (rowNum=1; rowNum<numOfRows+1; rowNum++){
                    let currentRow = rowWord + rowNum;
                    let sum = 0;

                    for (matrixNum = 0; matrixNum < numOfMatrices; matrixNum++) {
                        sum += parseInt(data[matrixNum].matrix.rows[currentRow].cols[currentCol]);
                    }
                    result.matrix.rows[currentRow].cols[currentCol] = "" + sum;
                }
            }
            console.log(result);
            return result;
        }
    }   
    
    
    const data = [
    {
      matrix: {
        rows: {
          ROW1: {
            cols: {
              COL1: "4",
              COL2: "2"
            }
          },
          ROW2: {
            cols: {
              COL1: "1",
              COL2: "4"
            }
          },
          ROW3: {
            cols: {
              COL1: "2",
              COL2: "1"
            }
          }
        }
      },
    },
    {
      matrix: {
        rows: {
          ROW1: {
            cols: {
              COL1: "1",
              COL2: "6"
            }
          },
          ROW2: {
            cols: {
              COL1: "2",
              COL2: "3"
            }
          },
          ROW3: {
            cols: {
              COL1: "5",
              COL2: "2"
            }
          }
        }
      }
    }
  ];

   sumMatrices(data);

答案 1 :(得分:0)

由于行和列的数量不是静态的,因此将应用递归函数来获取总和,而无需假定列或行的属性名称。

const data = [{
    matrix: {
      rows: {
        ROW1: {
          cols: {
            COL1: "4",
            COL2: "2"
          }
        },
        ROW2: {
          cols: {
            COL1: "1",
            COL2: "4"
          }
        },
        ROW3: {
          cols: {
            COL1: "2",
            COL2: "1"
          }
        }
      }
    },
  },
  {
    matrix: {
      rows: {
        ROW1: {
          cols: {
            COL1: "1",
            COL2: "6"
          }
        },
        ROW2: {
          cols: {
            COL1: "2",
            COL2: "3"
          }
        },
        ROW3: {
          cols: {
            COL1: "5",
            COL2: "2"
          }
        }
      }
    }
  }
];

var result = {};
var sum = function(from, to) {

  var keys = Object.keys(from);

  for (let i = 0; i < keys.length; i++) {
    if (to[keys[i]] === undefined) {
      to[keys[i]] = from[keys[i]];
    } else {
      if (typeof from[keys[i]] === "object") {
        sum(from[keys[i]], to[keys[i]])
      } else {
        to[keys[i]] = parseInt(from[keys[i]]) + parseInt(to[keys[i]]);
      }
    }
  }
};


for (index in data) {
  sum(data[index], result);
}

console.log(result);

答案 2 :(得分:0)

您可以尝试遍历对象的键,并随需添加值来构建最终结果。

const data = [
    {
        matrix: {
            rows: {
                ROW1: {
                    cols: {
                        COL1: "4",
                        COL2: "2"
                    }
                },
                ROW2: {
                    cols: {
                        COL1: "1",
                        COL2: "4"
                    }
                },
                ROW3: {
                    cols: {
                        COL1: "2",
                        COL2: "1"
                    }
                }
            }
        },
    },
    {
        matrix: {
            rows: {
                ROW1: {
                    cols: {
                        COL1: "1",
                        COL2: "6"
                    }
                },
                ROW2: {
                    cols: {
                        COL1: "2",
                        COL2: "3"
                    }
                },
                ROW3: {
                    cols: {
                        COL1: "5",
                        COL2: "2"
                    }
                }
            }
        }
    }
];

const sumMatrices = (array) => {

    const summed = { matrix: { rows: {} }};

    array.forEach((item) => {

        Object.keys(item.matrix.rows).forEach((row) => {

           if (!summed.matrix.rows[row]) summed.matrix.rows[row] = { cols: {} };

           Object.keys(item.matrix.rows[row].cols).forEach((col) => {

               if (!summed.matrix.rows[row].cols[col]) summed.matrix.rows[row].cols[col] = 0;

               summed.matrix.rows[row].cols[col] += +item.matrix.rows[row].cols[col];
           });
       });
    });

    return summed;
};  

console.log(sumMatrices(data));