Ways to revert a modified string back to its original format in JavaScript

I've been working on a sorting algorithm to intelligently sort filesizes regardless of the input format. The function is designed to sort an array of string inputs to produce the following desired outputs;

input = ["5.1 GB","19934563 B","224 kB","0.55 GB","0.04 kB","0.02 TB","2.4 MB"]
output = ["0.04 kB","224 kB","2.4 MB","19934563 B","0.55 GB","5.1 GB","0.02 TB"]

The code preprocesses the input to a specific format for easier manipulation before sorting the values. It currently produces the following result

input = ["5.1   GB ","19934563 B"," 224 kB","  0.55 GB ","0.04 kB ","0.02  TB","2.4\tMB",]
output =["0.04 kB ","224 kB","2.4 MB","19934563 B","0.55 GB","5.1 GB","0.02 TB",]

My Inquiry: Is there a way to revert back to the original string format after sorting, or how can I achieve the required outcome? That is, having the filesize string sorted intelligently in the original input format.

Below is the snippet of my code:

function sort(fileSizes, descending) {    
    if (!fileSizes.length) return "Enter an List to be Sorted";
    else {
      let validFormat = fileSizes.map((file) => validFile(file));
      if (validFormat.includes(false)) {
        let formarted = fileSizes.map(item => item.replace(/\s+/g,' ').trim());
        fileSizes = formarted;
      };
      let sortedFiles = sortSizes(fileSizes);
      if (descending === true ) return sortedFiles;
      if (descending === false) return sortedFiles.reverse();
    }    
  }

//////////////////////////////////////////////
//Helper Functions

//Regular expression for valid input format
function validFile(str) {
  let regEx = /^(-?\d*(\.\d+)?)\s((T|G|M|k)*B)$/;
  let valid = regEx.test(str);
  return valid;
}

 // global comparator array
let sizes = ["B", "kB", "MB", "GB", "TB"];

//Custom Sorter
function sortSizes(arr) {
  // sort by comparator
  arr.sort(function(x, y) {
    var x_res = x.split(" "), y_res = y.split(" ");
    var x_value = x_res[0], x_unit = x_res[1];
    var y_value = y_res[0], y_unit = y_res[1];
    let amount = casting(x_unit, y_unit, x_value);
    if(amount < y_value) {
      return -1;
    } else if(x_value > y_value) {
      return 1;
    } else {
      return 0;
    }
  });
  return arr.reverse();  
}

//Convert file unit for comparison
function casting(unit_from, unit_to, amount) {
  var i = sizes.indexOf(unit_from);
  var j = sizes.indexOf(unit_to);
  var r;
  if(i < j) {
    r = j - i;
  } else {
    r = j - i;
  }
  var i = 0;
  if(r < 0) {
    r *= (-1);
    while(i < r) {
      amount *= 1024;
      i++;
    }
  } else {
    while(i < r) {
      amount /= 1024;
      i++;
    }
  }  
  return amount;
}

console.log(sort(["5.1 GB","19934563 B","224 kB","0.55 GB","0.04 kB","0.02 TB","2.4 MB",], false)); // ["0.04 kB","224 kB","2.4 MB","19934563 B","0.55 GB","5.1 GB","0.02 TB",]
console.log(sort(["5.1 GB","19934563 B","224 kB","0.55 GB","0.04 kB","0.02 TB","2.4 MB",], true)); //["0.02 TB","5.1 GB","0.55 GB","19934563 B","2.4 MB","224 kB","0.04 kB"]
console.log(sort([], true)); //"Enter an List to be Sorted"
console.log(sort(["5.1   GB ","19934563 B"," 224 kB","  0.55 GB ","0.04 kB ","0.02  TB","2.4\tMB",], false));  //["0.04 kB "," 224 kB","2.4\tMB","19934563 B","  0.55 GB ","5.1   GB ","0.02  TB",]

Answer №1

const sizes = ["5.1   GB ","19934563 B"," 224 kB","  0.55 GB ","0.04 kB ","0.02  TB","2.4\tMB"]

const multipliers = {
  B: 10 ** 0,
  kB: 10 ** 3,
  MB: 10 ** 6,
  GB: 10 ** 9,
  TB: 10 ** 12,
}

sizes.sort((a, b) => {
  const spaceRegex = /\s+/;
  const [valueA, unitA] = a.trim().split(spaceRegex); 
  const [valueB, unitB] = b.trim().split(spaceRegex);
  const sizeA = Number(valueA) * multipliers[unitA];
  const sizeB = Number(valueB) * multipliers[unitB];
  return sizeA - sizeB;
})

console.log(sizes)

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

Issue with extraneous event being activated upon bootstrap collapse button usage

I have implemented a functionality using Bootstrap 5.2 where I have two buttons that can hide content by utilizing the Bootstrap collapse plugin. <div class="col-12 col-sm-auto"> <span class="pe-2"> ...

Java: Is there a way to generate an array of a specific type dynamically according to the object's type?

I am interested in converting a List that I know is uniform into an array with the same data type as its elements. For example... List<Object> list = new ArrayList<Object>; list.add(new Integer(3)); /// somewhere else ... assert(my_array i ...

Is there a way to add to a dropdown option in select2?

I am in need of creating a dropdown feature that offers users the ability to: 1. Automatically fill in options (based on predetermined values) 2. Add a brand new option if none of the current choices are suitable. I came across select2 as an easy way to i ...

Transitioning between javascript functions

Having some issues with a switch case statement, also tried using if-else but no luck. In the HTML code: <select onBlur="functionCalc()" id="art"> <option value="hours" id="hours">Hours</option> <option value="minutes" id="mins">M ...

The route parameters seem to be malfunctioning when using the Google Maps Directions API

Currently, I am attempting to transfer the latitude and longitude of a location from one HTML file to another using the $routeParams feature. In the second HTML file, I utilized the Google Maps directions API to display the directions from the source lati ...

Using React Bootstrap, you can ensure that only a single collapse opens at a time when rendering it with a map function. This allows you to display

When a user clicks on the "View Tasks" button, I want to display the relevant tasks specific to that user. However, currently all React Bootstrap Collapse Components open up and show tasks for every user instead of just one. This issue arises because the o ...

How to utilize a Boolean return value in React Class component following a promise fetch operation

Hello, I have a question about a class I am working on in React. When I call Auth.isAuthenticated() from another component, it always returns false, even though the server is returning a 200 response which should set this.authenticated to true. How can I ...

Reserve Your Room in Style with C++!

Seeking assistance with the Hotel Bookings Problem C++ from InterviewBit website. I've been struggling to find a solution to this particular question. The scenario is as follows: A hotel manager needs to process N advance bookings for rooms for an upc ...

Get to a certain nested div by using jQuery

Can someone assist me in accessing a specific element within a div while using a foreach loop? Below is the code snippet: HTML <div class="row menu-filter-items"> <div class="col-md-4 margin-b-30 menu-item"> <a href="#" class= ...

Understanding the significance of underscores in JavaScript strings

Some places mention using _() around strings like _('some string'). For instance, in a desktop program with these imports: const Applet = imports.ui.applet; const St = imports.gi.St; const Gdk = imports.gi.Gdk; const Gtk = imports.gi.Gtk; const ...

Alter the content of a div depending on the values of three different elements

Hello everyone, I am new to the world of jQuery and javascript, and I am facing a challenge that I need some help with. Within a form, there are two fields that I would like to perform calculations on. Here is what I have attempted so far: jQuery.fn.calcu ...

How can I use the jQuery map function to separate IDs with commas?

code: <script> $("#save_other").click(function(e){ e.preventDefault(); question = $(".question:checked").map(function() { return this.id; }).get().join(","); alert(question); ...

Do you think there is a more efficient way to solve this issue?

const [active, setActive] = React.useState(["active", "", "", "", ""]);``your unique text`` const hrefs = React.useMemo( () => ["/", "/about", "/skills", "/projects", "/contact"], [] ); React.useEffect(() => { setInterval(() => { ...

Is there a way to specify the width of an element as "fill_parent"?

Initially, I must mention that this question may appear similar to mine, but it is actually different. My HTML code is as follows: .parent{ border: 1px solid gray; width: 70%; } .title{ border: 1px solid green; } .input { /* width: fill_paren ...

The component is being mounted twice to ensure that an axios request is made successfully in an asynchronous test. If the component is only mounted once, the test will fail

When making a request to an internal server for data, I am using axios-mock-adapter to mock the response. The response is an array containing 5 items. To pass the test successfully, I have to mount the component twice. Below is the code for my component: ...

What is the best way to ensure that the radius of the circle adjusts according to the canvas element in

I've successfully drawn a circle on a canvas element, but now I need to make it responsive. How can I achieve this? I want the radius of the circle to change by a certain amount when the browser width or height changes. How do I calculate this changi ...

Change the Background of Your Body?

Here's the deal. I'm looking to create a cool effect where the background of the body slowly fades out and changes periodically in a loop using CSS and jQuery. Any suggestions on how I can make this happen? Appreciate your help! ...

Exploring the power of JavaScript Callback using nano and now.js

every.person.now.guessValue = function(value) { database.find('lists', 'project_names', { startingPoint: value, endingPoint: value + "\u9999" }, function(_, information) { return information.rows.map(function( ...

What is the best way to retrieve input attributes in Node.js?

How can I achieve the same functionality as the code snippet below using Node.js? selectedRadio = document.querySelector('input[name="device"]:checked').dataset.name; I am developing a backend using Node.js and Express.js with BodyParser for an ...

Troubleshooting Next.JS Fast Refresh failure on Windows with Ubuntu or WSL

When adjusting and saving files with reactJS/Next.JS, I encountered an issue where the server fails to recognize these alterations and update accordingly. I experimented with different settings based on various articles I came across, but unfortunately no ...