Vue.js - How to convert a simple array to dynamic NxNxN Matrix

99封情书 提交于 2020-01-26 04:00:13

问题


Imagine you have an array:

listItems = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13 ,14 ,15 ,16, 17, 18, 19, 20, 21, 22, 23];

And I want it to convert into 3-dimensional Array((Matrix of ROW x COLUMN)x SET by Number of Instances, like this:

Example: 3 Rows and 3 Columns = 1 Set

--GENERATED GRIDS--
A = [[1, 2, 3], [4, 5, 6],[7, 8, 9];
B =  [[10, 11, 12], [13, 14, 15], [16, 17, 18]];
C = [[19, 20, 21], [22,23]]

Note, that rows and columns of the matrix are changeable. Meaning that the number of items in the rows or column may change and even the amount of items in the data set may also differ.

Could you also provide an example so that I'm able to achieve the expected results below.

EXPECTED RESULT: (GENERATED TABLE includes html structure):

<HTML>
<CONTAINER>
//A SET
<div class "set">
   ROW 1: <row><div class "items"> 1 </div><div class "items"> 2</div><div class "items"> 3</div></row>
   ROW 2: <row><div class "items"> 4</div><div class "items"> 5</div><div class "items"> 6</div><row> 
   ROW 3: <row><div class "items"> 7</div><div class "items"> 8</div><div class "items"> 9</div></row>
 </div>
</div>

//B SET
<div class "set">
       ROW 1: <row><div class "items"> 10</div><div class "items"> 11</div><div class "items"> 12</div></row>
       ROW 2: <row><div class "items"> 13</div><div class "items"> 14</div><div class "items"> 15</div><row> 
       ROW 3: <row><div class "items"> 16</div><div class "items"> 17</div><div class "items"> 18</div></row>
     </div>
    </div>

//C Set
<div class "set">
           ROW 1: <row><div class "items"> 19</div><div class "items"> 20</div><div class "items"> 21</div></row>
           ROW 2: <row><div class "items"> 22</div><div class "items"> 23</div></row>
         </div>
        </div>



</CONTAINER>
</HTML>

Answer Format Template:

<template>
<container>

 <LOOP THROUGH ALL SETS>
  <div class ="set">
    <SOME CODE LOOP THROUGH MATRIX 1 - ROW and COLUMN>
  </div>
  <div class ="set">
    <SOME CODE LOOP THROUGH MATRIX 2 - ROW and COLUMN>
  </div>
  <div class ="set">
    <SOME CODE LOOP THROUGH MATRIX 3 - ROW and COLUMN>
  </div>

  ...
  ...


 <END LOOP THROUGH ALL SETS>

<container>

</template>

<script>
export default {
components: {
},
computed: {
 <SOME CODE USE TO PROCESS ARRAY INTO N x N x N... >
},
data () {
      return {
        itemPerCol:3,
        itemsPerRow: 3,
       listItems:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ,13 ,14 ,15 ,16, 17, 18, 19, 20, 21, 22, 23],
</script>

<style>
</style>

Please provide Vue.JS compatible answers if possible as Vue.JS is very sensitive

Any help is much appreciated.


回答1:


You can reshape the array using vanilla JS.

const range = (start, stop) => Array(stop - start).fill(0).map((n, i) => i + start);
const equals = (actual, expected) => JSON.stringify(actual) === JSON.stringify(expected);

const expected = [
  [ [  1,  2,  3 ], [  4,  5,  6 ], [  7,  8,  9 ] ],
  [ [ 10, 11, 12 ], [ 13, 14, 15 ], [ 16, 17, 18 ] ],
  [ [ 19, 20, 21 ], [ 22, 23, 24 ], [ 25, 26, 27 ] ],
];

console.log(equals(reshape(range(1, 28), 3, 3), expected)); // range = [1, 27]

function reshape(list, perCol, perRow) {
  let result = [];
  for (let i = 0; i < list.length; i++) {
    let row  = Math.floor(i / (perCol * perRow)),
        col  = Math.floor((i / perRow) % perRow),
        item = Math.floor(i % perCol);
    result[row]            = result[row]      || []; // lazy init
    result[row][col]       = result[row][col] || []; // lazy init
    result[row][col][item] = list[i];
  }
  return result;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

An example of a "table" generated from the matrix.

const matrix = [
  [ [  1,  2,  3 ], [  4,  5,  6 ], [  7,  8,  9 ] ],
  [ [ 10, 11, 12 ], [ 13, 14, 15 ], [ 16, 17, 18 ] ],
  [ [ 19, 20, 21 ], [ 22, 23, 24 ], [ 25, 26, 27 ] ],
];

renderMatrix(matrix);

function renderMatrix(matrix, target) {
  let containerEl = document.createElement('div');
  containerEl.className = 'container';
  for (let s = 0; s < matrix.length; s++) {
    let setEl = document.createElement('div');
    setEl.className = 'set';
    for (let r = 0; r < matrix[s].length; r++) {
      let rowEl = document.createElement('div');
      rowEl.className = 'row';
      for (let c = 0; c < matrix[s][r].length; c++) {
        let itemEl = document.createElement('div');
        itemEl.className = 'item';
        itemEl.textContent = matrix[s][r][c];
        rowEl.appendChild(itemEl);
      }
      setEl.appendChild(rowEl);
    }
    containerEl.appendChild(setEl);
  }
  (target || document.body).appendChild(containerEl);
}
.container {
  border: thin solid black;
}
.set {
  border: thin solid green;
  margin: 0.5%;
  width: 98.5%;
}
.row {
  display: inline-block;
  border: thin solid red;
  margin: 0.5%;
   width: 31.75%;
}
.item {
  display: inline-block;
  width: 28%;
  margin: 2%;
  border: thin solid blue;
  text-align: center;
}



回答2:


A quick bug fix to @MrPolywhril's solution posted above.

function reshape(list, perCol, perRow) {
  let result = [];
  for (let i = 0; i < list.length; i++) {
    let row  = Math.floor(i / (perCol * perRow)),
        col  = Math.floor((i / perCol) % perRow),
        item = Math.floor(i % perCol);
    result[row]            = result[row]      || []; // lazy init
    result[row][col]       = result[row][col] || []; // lazy init
    result[row][col][item] = list[i];
  }
  return result;

This slight modification allows for the dynamic create of any designed Column(perCol) x Row(perRow) matrix set. Meaning that you will be able to made a [4 x 2], [5 x 3] etc. matrix without any missing elements during creation. @MrPolywhril's first solution only successfully creates square matrix [4 x 4], [2 x 2], [5 x 5] sets without missing elements.



来源:https://stackoverflow.com/questions/58837931/vue-js-how-to-convert-a-simple-array-to-dynamic-nxnxn-matrix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!