Public Solving: Elf Post Service package calculator

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

In today's puzzle, we get asked by Santa himself to optimize their package performance.
Great idea, since Amazon seems to suck at this! And it's wasteful to use big boxes when having smaller ones available.
So, it's up to us to find the best fit package for each item we are packing. Luckily, we only have to work with one item per box query. However, the item could be rotated, making it more complicated.
To determine if an item fits in a box, we have to loop over each box and find the smallest box.
The boxes are already in order of size, so we don't need to introduce a new function for this.
My first thought was actually to check if each element is equal to or smaller than the box like so:
item.width <= box.width &&
item.length <= box.width &&
item.height <= box.height;
This would partially work. In some cases, we would still get a bigger box, which means the item could be rotated inside the box to fit!
We could manually write out to check for each possible combination, but that would get very difficult to understand.
So my new idea is to calculate the item's surface and the box surface.
Let's create a function for that.
const calculateSurface = (item) => {
return item.length * item.width * item.height;
};
This function will retrieve an item (box or item) and calculate the surface.
Then we can work on the selectBox function. The easiest way to handle this is to use the find method, as this will stop the moment it has a hit.
return boxes.find((box) => {
return (
calculateSurface(item) <= calculateSurface(box)
);
});
This will return if the item surface is smaller than the box surface.
However, there is a catch here!
Let's take this item: 3x3x80 it has a surface of 720.
And our tool states it fits in a petit box with the following dimensions: 20x20x10, which gives a surface of 4000.
But there is no way this will fit, as the 80 is way bigger than the 20...
That means we have to introduce another check, which will find the biggest side of an item, and makes sure it doesn't exceed the biggest side of the box.
Let's create that function.
const biggestSide = (item) => {
return Math.max(...Object.values(item).filter(Number));
};
Bear with me. A lot is going on here.
First, we use Object.values to get all the values of the item we pass in.
Then we filter out only the numbers. This will remove the strings for the box.
Then we spread the values into a single array, and retrieve the highest number using the Math.max function.
All we have to do is introduce this as the second option for our find method.
return boxes.find((box) => {
return (
calculateSurface(item) <= calculateSurface(box) &&
biggestSide(item) <= biggestSide(box)
);
});
Let's give it a test run and see what happens.

We did it!
Let me know what you think of this solution or what you would do differently.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter