-1

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.

  • This question makes little sense to me. You want to create three-dimensional matrix, but end up with 3 two-dimensional matrices where one of the matrices is invalid. Other than that, you should be able to calculate where an item has to go with modulo and the index of that item. – Sumurai8 Nov 13 '19 at 13:32

2 Answers2

0

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;
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • @ShiftyCosmii huh? How is reshaping a 1-D array into 2-D, 3-D, ..., _n_-D array not what you want? My second answer is just a way to present an already 3-D matrix. – Mr. Polywhirl Nov 14 '19 at 00:23
  • @Mr.Polywhril By combining your two solutions together, I got my excepted results. So using the top solution of creating a Matrix based on Row and Columns from a single array and then passing that into the render Matrix. `renderMatrix(reshape(range(1, 27), 3, 3));` – ShiftyCosmii Nov 14 '19 at 02:53
  • @ShiftyCosmii I separated them by concept, but I did not want to add a third example. Nice that it guided you in the right direction. – Mr. Polywhirl Nov 14 '19 at 03:23
0

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.