Arranging an Array of Objects in JavaScript by dual criteria

In my JavaScript code, I have an object structured like this:

myArray[0] -> 0:"62", 1:8, 2:0, 3:"11"
myArray[1] -> 0:"62", 1:8, 2:0, 3:"15"
myArray[2] -> 0:"48", 1:8, 2:0, 3:"04"
myArray[3] -> 0:"48", 1:8, 2:0, 3:"01"
myArray[4] -> 0:"62", 1:8, 2:0, 3:"12"
myArray[5] -> 0:"48", 1:8, 2:0, 3:"02"
myArray[6] -> 0:"62", 1:8, 2:0, 3:"14"
myArray[7] -> 0:"48", 1:8, 2:0, 3:"03"

I am looking to rearrange it as follows:

myArray[0] -> 0:"48", 1:8, 2:0, 3:"01"
myArray[1] -> 0:"48", 1:8, 2:0, 3:"02"
myArray[2] -> 0:"48", 1:8, 2:0, 3:"03"
myArray[3] -> 0:"48", 1:8, 2:0, 3:"04"
myArray[4] -> 0:"62", 1:8, 2:0, 3:"11"
myArray[5] -> 0:"62", 1:8, 2:0, 3:"12"
myArray[6] -> 0:"62", 1:8, 2:0, 3:"14"
myArray[7] -> 0:"62", 1:8, 2:0, 3:"15"

To achieve this ordering, I need to sort by myArray[i][0] first, and then sort by myArray[i][3] based on the initial index of myArray[i][0]. Although I've managed to sort by myArray[i][0] using

myObject.sort(function(a, b){ 
    return parseInt(a) - parseInt(b); 
});

I still need help on how to accomplish this without using any external libraries. Any guidance would be appreciated.

Answer №1

To optimize sorting, I recommend utilizing chained comparison functions in a single run.

Understanding how the Array#sort() function operates:

When a custom compareFunction is provided, the array elements are sorted based on its return value. For two elements being compared, denoted as a and b:

  • If compareFunction(a, b) evaluates to less than 0, a precedes b in the sorted sequence.

  • If compareFunction(a, b) returns 0, a and b retain their relative positions but are sorted concerning other elements. Note: not all browsers adhere to this behavior as outlined in the ECMAscript standard.

  • If compareFunction(a, b) yields a value greater than 0, b comes before a in the sorted order.
  • The compareFunction must consistently produce the same output for a specific pair of elements a and b; otherwise, the sort outcome becomes undefined.

In the present scenario, the compare function features two sets of rules, one for sorting at index [0] and another for index [3]. If the values at index [0] are equal, then the sorting criteria at index [3] come into play. These rules are linked together using logical OR ||.

var array = [["62", 8, 0, "11"], ["62", 8, 0, "15"], ["48", 8, 0, "04"], ["48", 8, 0, "01"], ["62", 8, 0, "12"], ["48", 8, 0, "02"], ["62", 8, 0, "14"], ["48", 8, 0, "03"]];

array.sort(function (a, b) {
    return a[0].localeCompare(b[0]) || a[3].localeCompare(b[3]);
});

document.write('<pre>' + JSON.stringify(array, 0, 4) + '</pre>');

Answer №2

In my view, the variable presented appears to be structured as an Array (an object indexed with integer keys). In this scenario, a possible solution could be:

var ar = [
  ["62", 8, 0, "11"],
  ["62", 8, 0, "15"],
  ["48", 8, 0, "04"],
  ["48", 8, 0, "01"],
  ["62", 8, 0, "12"],
  ["48", 8, 0, "02"],
  ["62", 8, 0, "14"],
  ["48", 8, 0, "03"]
]

var result =  ar.map(function(a) {
  return {key: a.join(''), val: a}
}).sort(function(a, b){ 
  return parseInt(a.key, 10) - parseInt(b.key, 10);
}).map(function(a) {
  return a.val
})
console.log(result)

Check out the updated version on this JSFiddle link

Edit

Alternatively, you can explore the Object approach:

var data = [{ 0:"62", 1:8, 2:0, 3:"11"},{ 0:"62", 1:8, 2:0, 3:"15"},
            { 0:"48", 1:8, 2:0, 3:"04"},{ 0:"48", 1:8, 2:0, 3:"01"},
            { 0:"62", 1:8, 2:0, 3:"12"},{ 0:"48", 1:8, 2:0, 3:"02"},
            { 0:"62", 1:8, 2:0, 3:"14"},{ 0:"48", 1:8, 2:0, 3:"03"}]

var result =  data.map(function(a) {
  return {key: [0,1,2,3].map(function(k) {return a[k]}).join(''), val: a}
}).sort(function(a, b){ 
  return parseInt(a.key, 10) - parseInt(b.key, 10);
}).map(function(a) {
  return a.val
})
console.log(result)

Access the improved version through this updated JSFiddle link

Edit 2

In response to @malixsys's feedback, a more efficient implementation is available:

var result =  data.sort(function(a, b){ 
  return parseInt(a[0]+ a[1] + a[2] + a[3], 10) - parseInt(b[0]+ b[1] + b[2] + b[3], 10);
})

You can view the optimized code by clicking on this revised JSFiddle link

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 regular expression that can identify whether a string is included in a numbered list?

Struggling with creating a regular expression to determine if a string is part of a numbered list like those in word processors. Need it to return true only if the string starts with a number, followed by a full stop and a space. Easy for single or doubl ...

AngularJS - Issue: [ng:areq] The 'fn' argument provided is not a function, instead it is a string

I encountered an issue: Error: [ng:areq] Argument 'fn' is not a function, received string Despite following the recommendations of others, I still have not been able to resolve the problem. Below is the code snippet in question: controller. ...

Issues arise when attempting to extract data from a data provider using JSON within the context of the Ionic framework

Hey there! I'm relatively new to the world of Angular and Ionic, and I've embarked on a project to create a pokedex app. My approach involves using a JSON file containing an array of "pocket monsters". However, my current challenge lies in extrac ...

Express JS redirect does not update the URL and fails to load static files

I'm currently developing an application using Express.js to build the REST interface on Node.js. Additionally, I am using jQuery Mobile for the client-side pages. One issue I am facing is with redirects when users try to access a restricted or inacce ...

Trouble with sending input through Ajax in HTML form

I'm facing a dilemma that I can't solve. The issue arises from a page (index.php) that begins by opening a form, then includes another PHP page (indexsearch.php), and finally closes the form. The included page works with a script that displays d ...

Click on the sort icon in React JS to change its state

I need to update the sort icon in my table header when a user sorts a column. Here is the current implementation of my sorting function: var headerColumns = []; var IconType = 'triangle'; var IconSort = 'top'; var onToggleO ...

After closing, the position of the qtip2 is being altered

I've successfully integrated the qtip2 with fullcalendar jQuery plugin, which are both amazing tools. However, I'm encountering an issue with the positioning of the qtip. Here's the code snippet I'm using: $(window).load(function() { ...

Connect the dxSelectBox to the button click event

Currently, I am working with the DevExtreme MVVM architecture. In my specific situation, I am trying to bind a dxSelectBox (combo box) upon a button click event. Here is the HTML CODE snippet: <div data-bind="dxButton:{onClick:display,text:'Click ...

Adjust the width of the TinyMCE Editor to automatically resize based on the content being

Is it possible for TinyMCE to adjust the content within an absolutely positioned container and update the width while editing? <div class="container"> <textarea>This is my very long text that should not break. This is my very long text tha ...

Discovering the art of interpreting the triumphant outcome of an Ajax request with jquery/javascript

I recently encountered a challenge with my function that deals with a short JSON string: <script id="local" type="text/javascript"> $( document ).ready(function() { $('tr').on('blur', 'td[contenteditable]', functi ...

Why isn't this working? I'm attempting to trigger a sound when I hover with my cursor, but it only plays when I click instead

When I click on it, it works fine. But I can't seem to get it to work on hover. Can someone help me out? This is the HTML code: <body> <audio autoplay id="HAT2" > <source src="OOOOO_1_HAT.mp3" > Your browser doesn't support t ...

What is the best way to eliminate the border on Material UI's DatePicker component?

Check out this code snippet for implementing a datepicker component: import React, { Fragment, useState } from "react"; import { KeyboardDatePicker, MuiPickersUtilsProvider } from "@material-ui/pickers"; import DateFnsUtils from &qu ...

AngularJS and Handlebars (npm)

Is it possible for angularJS to function as a substitute for the "view engine" in nodeJS? I am seeking insights on the optimal method to use. (Do MEAN Stack developers utilize view engines? Or do they prefer using res.sendFile along with tools like ui-ro ...

Creating methods that are shared, privileged, and publicly accessible: A guide

Currently, some methods in one of my classes are public but can access private variables due to being privileged. This is because they are generated in the class constructor, allowing their closure to have access to the object closure. However, I am conce ...

Guide to creating a synchronous wrapper for jQuery ajax methods

I've made the decision to switch from synchronous ajax calls to asynchronous ones due to lack of support in most modern browsers. My code is currently reliant on synchronous (and dynamic) ajax calls to client-side functions that must be completed befo ...

Guide on how to trigger the opening of a side panel with a button click in Vue.js

Embarking on my first Vue app development journey, I find myself in need of guidance on how to trigger the opening of a panel by clicking a button within the header. Starting off with a simple HTML template, my goal is to add some interactivity upon click ...

From PHP to Javascript and back to PHP

I'm currently tackling an issue within my project: My database, utilizing PHP, provides an array containing a collection of JavaScript files that require loading. This list is stored in the $array(php) variable. My task is to extract these source fil ...

Automatically customizable CSS border thickness

Consider the following example of a div element: <div style="height: 10%; width: 20%; border: 1px solid black"> Div Content </div> The div above has its height and width specified in percentages. I would like the border width to adjust a ...

Perform an action when the timer reaches zero

I am working with a database entry that contains the following information: { _id:"fdjshbjds564564sfsdf", shipmentCreationTime:"12:17 AM" shipmentExpiryTime:"12:32 AM" } My goal is to create a timer in the front end ...

` Why isn't Glide.js functioning correctly when incorporated into a Bootstrap 4 modal component?`

I'm currently utilizing Glide.js and a Bootstrap 4 modal on our team page to showcase the biography of the selected team member. This functionality is achieved by extracting the attribute of the clicked team member and using it as the startAt: index f ...