0
\$\begingroup\$

I have a website where my users can create "table-like" layout dynamically. So imagine that my users can upload a text document, and then append columns to the document, and the output will then be parsed into a table-like layout.

For example:

My text document              Date: 20-06-2019                Created by: OJN

Content                       Nice Document                   Very!

Content                       Indeed!

                              Even more!

Now imagine that this is a word document for example, and my users have defined two columns on above (right between each block of text). This would output:

{
   "1":[
      {
         "row":"My text document"
      },
      {
         "row":"Content"
      },
      {
         "row":"Content"
      }
   ],
   "2":[
      {
         "row":"Date: 20-06-2019"
      },
      {
         "row":"Nice Document"
      },
      {
         "row": "Indeed!"
      },
      {
         "row": "Even more!"
      }
   ],
   "3":[
      {
         "row":"Created by: OJN"
      },
      {
         "row":"Very!"
      }
   ]
}

As you can see, this will ultimately generate three array objects with unequal elements.

0: Array(3)
1: Array(4)
2: Array(2)

Now when presenting this for the user in the frontend, I wish to show the parsed text content in a table, like: this

<table border="1">
  <tbody>
    <tr v-for="(row, index) in dataTable" :key="index">
      <td v-for="(cell, index) in row" :key="index">
        <span v-if="cell">{{cell["row"]}}</span>
      </td>
    </tr>
  </tbody>
</table>

However, as said, the arrays are of unequal length - so if I "just" transpose them, it will not generate the desired output. Instead, in above example, it will only create 3 rows in my table, because the first array contains 3 elements.

So in order to overcome this, I check the arrays to find the largest one:

// Transform object in array of its values
let data = Object.values(content);
let colsLength = data.map(r => r.length);
let maxNumCols = Math.max.apply(Math, colsLength);
let recordArraySchema = Array.apply(null, Array(maxNumCols)).map((r, i) => i);

this.dataTable = recordArraySchema.map((col, i) => data.map(row => row[i]));

This way, the array transposing will transpose all "rows", and fill the "empty"/non-existing will null, resulting in a full table.

I was wondering if this approach is acceptable in terms of performance and readability? I do have the option to change the JSON string format all together on the backend if that is more appropriate. However, I do have other backend functions that relies on the current schema, so those would have to be updated as well.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.