Creating a dynamic NxNxN matrix from a basic array in Vue.js

Consider 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];

I would like to transform it into a 3-dimensional Array((Matrix of ROW x COLUMN)x SET according to the number of instances. Here is an example:

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 the rows and columns of the matrix are flexible. This means that the number of items in each row or column may vary, as well as the quantity of items in the data set.

Could you please provide an example to help 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>

If possible, kindly provide Vue.JS compatible solutions as Vue.JS can be quite sensitive

Your assistance is greatly appreciated.

Answer №1

One way to modify the array is by using vanilla JavaScript.

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; }

This code snippet showcases how a "table" can be generated from a 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;
}

Answer №2

A small tweak to improve @MrPolywhril's previously shared solution.

function reorganize(inputList, columns, rows) {
  let output = [];
  for (let i = 0; i < inputList.length; i++) {
    let currentRow  = Math.floor(i / (columns * rows)),
        currentColumn  = Math.floor((i / columns) % rows),
        currentItem = Math.floor(i % columns);
    output[currentRow]            = output[currentRow]      || []; // initialize if needed
    output[currentRow][currentColumn]       = output[currentRow][currentColumn] || []; // initialize if needed
    output[currentRow][currentColumn][currentItem] = inputList[i];
  }
  return output;

This adjustment allows for the flexible creation of any Column x Row matrix setup. It now enables creating matrices like [4 x 2], [5 x 3] without missing elements during construction. The original solution by @MrPolywhril only handled square matrices like [4 x 4], [2 x 2], [5 x 5] without skips.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to continuously run jQuery code or reset it?

Can you help me create a loop that will continuously run this script after it finishes executing, repeating the process indefinitely? I want to keep running this code over and over again. This script is using jQuery version 3.5.1 // Title var title1 ...

A method in TypeScript for defining a type as a combination of interfaces within a union, specified as [one of union of interfaces] & {//attributes}

// Here's a way to define types in TypeScript: interface SudoA { foo: string; } interface SudoB { bar: string; } type Sudo = SudoA | SudoB; type SuperSudo = Sudo & { super: boolean; } const baz: SuperSudo = { } // TypeScript (3. ...

Encountered an issue while attempting to create a Higher Order Component using React and

Encountered an issue while using recompose to create a Higher Order Component (HoC) with withState and lifecycle: warning.js?8a56:36 Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM eleme ...

Please ensure that the function chain has appropriate parameter and return types by specifying the tuple type

Can a new type be created for the given tuple/array that has certain validation constraints? The following array is considered valid: const funcs = [(a: string) => 1, (a: number) => 'A', (a: string) => 2] However, this one is invalid ...

Error: AngularJS: Invalid Argument Error. The argument 'ClientCtrl' is not defined as a function, it is currently undefined

As a newcomer to AngularJS, I am facing an issue while trying to add a controller to my website. Strangely, the other two controllers are functioning perfectly fine, but this particular one is not being recognized. Here is my app.js file: var app = angul ...

Setting limits on relational data in Nest.js involves utilizing the appropriate decorators and methods to restrict

In my Nest.js application, I am working with relational data and using the TypeOrm query builder to retrieve the data. Here is an example of how I am querying the data: async find() { return this.landingSectionNameRepository.createQueryBuilder(&apo ...

Swapping out a character on a webpage using jQuery

Can someone help me remove the colon from this code snippet on my webpage? <h1><b>Headline:</b> something</h1> I'm looking for a simple solution using jQuery, as I am a beginner in JavaScript. Please include the complete code ...

How can we retrieve the isolated directive scope variable in the link function of AngularJS?

Check out the code snippet provided below. directive: app.directive("filterTree", function() { return { restrict: "AE", controller: function($scope, $http){ $scope.treeNodes = []; var filterItemsUrl = "/api/v1/ ...

Provide a random number that is not already listed in the array

I am working on creating a function that accepts an array as input, generates a random number between 1 and 10, keeps generating numbers until it finds one that is not in the array, and then returns that number. For more information and to see the code in ...

Leverage the power of AJAX to execute a PHP script and obtain a singular value in

After this question was closed due to lack of clarity, I decided to rewrite it in a more concise manner... Task: Develop a Room Booking System Objective: Create a function that checks the database for existing bookings based on specific criteria. The fun ...

The sidebar I designed didn't completely extend across the column in Bootstrap

My sidebar in Bootstrap didn't fill the entire column because I forgot to set a specific width for it. Here is the CSS code for my sidebar: .sidebar { position: fixed; /* top: 0; bottom: 0; left: ...

JavaScript - Struggling with decoding a JSON object

Having some difficulty with JSON object parsing, Take a look at my code: var data = '[{"image:loc":["https://cdn.shopify.com/s/files/1/0094/2252/products/YZY-KW3027.053.jpg?v=1539344090"],"image:title":["Yeezy WMNS Tubular Boot Washed Canvas - Limes ...

Utilizing ReactJS for Web Development with Enhanced Data Insights from Google

Utilizing Google Analytics and various tools, I've encountered an issue with the development of ReactJS. My goal was to collect analytics data from my website by using react-helmet to dynamically change the title and the HTML lang parameter based on t ...

Attempting to use Model.remove() is proving to be completely ineffective

Currently, I am utilizing expressjs (version 3.10.10), mongoose (version 3.10.10), and mLab for my project. Below is the code snippet: app.get("/deleteDevice/:query", function(req, res) { var query = req.params.query; query = JSON.stringify(quer ...

issue encountered while passing a callback in a res.render() function

Currently, I am working on a small application where I am fetching data from remote JSON files to generate statistics that will be displayed in an EJS file later. My objective is to pass separate values for rendering and then utilize them within the EJS d ...

Could you advise on the best placement for my upcoming JQuery animation?

Here is the code I am currently working with: $(function() { $("button").click(function() { $("#box1").animate({ left: $(window).width() - 800 }, { complete: function() { $("#box1").hide(); } }); $("#box2").a ...

The jQuery ajax function is not properly displaying or hiding the loader div

While attempting to call PHP code using a jQuery AJAX function, I encountered an issue where I wanted to display a loader div while the request was being sent and then hide the div once the request was complete. To simulate this scenario, I deliberately de ...

Unable to include a JavaScript file within another JavaScript file

Currently, I am working on a project where I am utilizing Django for the backend and HTML/CSS/JS for the frontend development. On a specific HTML page, I am including two JS files: dom_creator.js and console_page.js. My goal is to access the functionaliti ...

Selecting radio buttons using Bootstrap and JavaScript

I'm interested in incorporating this bootstrap radio selection feature into my JavaScript code. For example, if option1 is true, I want to execute a specific action... How can I achieve this? <div class="alert alert-info" role="alert"> < ...

Error in NodeJS: 'Cannot alter headers once they have been sent.'

My project involves developing an app with Express that fetches tweets from Twitter. Each API call retrieves 200 tweets (or fewer if there are less than 200) and in total, I need to retrieve 1800 tweets. To achieve this, I use a time interval to make multi ...