JavaScript: Arranging Data in a Matrix Based on Optimal Placement

How can one efficiently organize a dynamic matrix for optimal fit? Imagine you need to constantly display items in the best possible way, with no gaps between them. Each item can have a size ranging from 1 to 12, and each row can have a maximum width of 12. Given a sample dataset, how would you dynamically sort and generate a new array that fits the display perfectly?

let exampleMatrix = [{
  size: 10,
  type: 'card'
}, {
  size: 4,
  type: 'card'
}, {
  size: 2,
  type: 'card'
}, {
  size: 11,
  type: 'card'
}, {
  size: 6,
  type: 'card'
}];


let resultArray = [
  [{
    size: 10,
    type: 'card'
  }, {
    size: 2,
    type: 'card'
  }],
  [{
    size: 4,
    type: 'card'
  }, {
    size: 6,
    type: 'card'
  }],
  [{
    size: 11,
    type: 'card'
  }]
];

What is the significance of this for the user? This process is crucial when generating dynamic data for a UI and ensuring that the components are optimized for space.

Answer №1

It appears that the challenge presented here aligns with what is known as the bin packing problem.

Solving this particular problem isn't an easy feat, and achieving more accurate outcomes can lead to solutions that are increasingly complex.

Featured below is a basic greedy algorithm intended to address your issue with a rough approximation. While it's feasible to enhance matches, doing so will add complexity and computational expense.

The provided solution utilizes recursion and adheres to a functional style, per my preference; however, a cleaner and less costly algorithm could be devised if avoiding functional or recursive techniques is preferred.

const matrixExample = [{
  size: 10,
  type: 'card'
}, {
  size: 4,
  type: 'card'
}, {
  size: 2,
  type: 'card'
}, {
  size: 11,
  type: 'card'
}, {
  size: 6,
  type: 'card'
}];

const sumCardList = cardList => cardList.reduce((prev, curr) => prev + curr.size, 0);

const packNextToBin = (cards, bins, max) => {
  if (cards.length === 0) {
    // there are no more cards to pack, use bins as is
    return bins;
  }
  
  // get the next card to pack into the bins
  const cardToPack = cards[0];
  
  // get the indices of bins which can still be filled
  const availableBinIndices = bins
    .map((bin, i) => ({sum: sumCardList(bin), index: i}))
    .filter(binData => binData.sum + cardToPack.size < max)
    .map(binData => binData.index);
    
  // if there are no more bins which can fit this card, makea new bin  
  if (availableBinIndices.length === 0) {
    const updatedBins = [
      ...bins,
      [
        cardToPack
      ]
    ];
    
    return packNextToBin(
      cards.slice(1),
      updatedBins,
      max
    );
  }
  
  // get the first available bin which can accept the card
  const binToPack = availableBinIndices[0];
    
  // get a version of the matched bin with the new card added  
  const binWithInsertion = [
    ...bins[binToPack],
    cardToPack,
  ];
  
  // get the bins with the updated bin updated
  const updatedBins = bins
    .map((bin, i) => i === binToPack ?
      binWithInsertion :
      bin
    );
  
  // pack the next card into the bins
  return packNextToBin(
    cards.slice(1),
    updatedBins,
    max
  );
}

const results = packNextToBin(matrixExample, [[]], 12)

console.dir(results)

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

Inquire about understanding Mean.js through form submission

Hey there, I'm looking to create a search engine for an application using JS MEAN. I have a database with various elements and I want users to fill out a form to see the results in a separate view. I haven't had much luck so far, I've don ...

Hide the .prev button on the jQuery slider when it is on the first

Is there a way to hide the .prev button when it is the first one? Also, why does the slider go back to the first slide when the .prev button is clicked at the last slide? How can this issue be resolved? var nextPane = function (e) { e &&am ...

The health check URL is experiencing issues: Unable to locate any routes

I am currently developing a .net Core 2.2/Angular 8 application and recently came across the HealthCheck feature. I decided to incorporate it into my application, so here is a snippet from my Startup.cs file: using HealthChecks.UI.Client; using Mi ...

Steps to Extract the key value from the parseJson() function

Could someone assist me in retrieving the value of the "id_user" key from the script provided below? JSON.parse({ "data": [ { "id_user": "351023", "name": "", "age": "29", "link": "http://domain. ...

Regular expression for finding CSS key-value pairs

Currently, I am utilizing regular expressions to identify CSS values. The input string that needs to be matched is: font-size:25px;font-family:georgian;content:"' unicode given in pseudo &#169; '"; The specific regex pattern I am using fo ...

Best practices for selecting checkboxes and transferring values to another page in PHP/HTML

Apologies for my lack of experience in PHP. I am in the process of creating a project without any knowledge of PHP. I have set up a database with a list of users and can display users based on specific information through a search. Each search query has a ...

Limit the maximum value for a NUMBER input in vue - a step-by-step guide!

Currently, I am attempting to develop a new input function that will reject any number entered by the user if it exceeds a specified limit. However, I have encountered some issues with this. Let's assume the maximum allowed number is 99. Currently, m ...

Implementing AJAX notifications in a contact form integrated with PHP, Google reCAPTCHA, and SweetAlert

I've implemented an AJAX script to handle the submission of a basic contact form with Google reCAPTCHA at the end of my HTML. Here's the relevant HTML code: <div class="col-md-6"> <form role="form" id="form" action="form.php" method ...

Tips for positioning the footer in HTML and CSS

footer { background-color: #000000 } .footer-nav { list-style: none; } .footer-nav li { display: inline-block; margin: 15px; font-weight: 400; font-size: 80% } .social { list-style: none; } .social li { display ...

Sending a Thunk to the store using Typescript

Within my primary store.ts file, the following code is present: const store = createStore( rootReducer, composeWithDevTools(applyMiddleware(thunk)) ); store.dispatch(fetchUser()); Upon initial rendering, an action is dispatched to fetchUser in ord ...

ng-src unable to bind the data

Utilizing ng-repeat to dynamically fetch my URL and using ng-src to connect that URL through AngularJS. Here is the code: <div class="x_panel" ng-repeat="data in allreviewdata|filter:search"> <div class="x_content"> <div ...

Is there a way to execute a condition in a Vue component before rendering the HTML in the template?

Here is an example of my Vue component: <template> <div id="modal-transaction" class="modal fade" tabindex="-1" role="dialog"> ... <div class="modal-header"> <h4 class="modal ...

Performing iterative calculations in Python

I am currently attempting to create an entropy function from scratch, as requested by my supervisor. I have a dataset called Ttrain, which contains several variables, including gender. My task involves extracting the categories (male and female), then calc ...

I am looking to save a collection of variables in an array and store it as a $_SESSION variable

Looking to store an array of variables as a $_SESSION variable in order to use it in another .PHP file and perform operations with it. The array: <script> var idArray = [18, 28, 31, 38, 41]; </script> What I attempted, but didn't suc ...

Unable to retrieve slots from child component's dynamic function in Vue2

When passing <slot name="success-mark"> to a child component, it is done as shown below: <vue-dropzone ref="myVueDropzone" id="dropzone" :options="dropzoneOptions"> <slot name="success-mark"><i class="fa fa-trash"></i>& ...

Only ONE number is being printed in the array

Having some difficulties with displaying my array in an asp:Label. The array consists of 5 numbers, but only one number is printed when assigning id.Text = arrayname; Check out the method below: void random4helper() { Random rand = new Random(); ...

When attempting to send data to the ServiceStack RESTful service, an error message of 'Access is denied' was received

I created a RESTful service using ServiceStack to send data to a database. It worked perfectly when tested locally. However, after deploying it to a server and running the same jQuery $.ajax call code, I encountered an 'Access is denied' error. I ...

Troubleshooting: Jquery Toggle Issue When Used with Adjacent Div Element

I've been puzzling over this issue for hours now. The intention of this code is to display a div, but it's just not cooperating. <div id="butbr"> <div id="sup_nav"> <div id="stup" class="bxt1"></div> <div id= ...

Leveraging jQuery to dynamically load an icon based on the content within a <label> tag

I manage a website that dynamically fetches content from a database, with varying contents for each label. For example, one label may be generated as General:, while another may be generated as TV:. My question is, can jQuery be used to replace the text NA ...

I want to initiate a Python script by clicking a button on my HTML page with the help of Ajax

Here is my JavaScript code: function executePython() { alert("executed"); $.ajax({ url: "http://localhost:5000/app.py", type: "POST", ...