Arrange JSON using JavaScript based on an alternative array order and the remaining items alphabetically

I need help sorting a JSON items with Javascript based on another array, and then alphabetically for the rest of the items.

Here is the array of the desired order for sorting the JSON items:

var order = [3,9,50,7];

The JSON data has an "ID" key that I want to sort using the order array, and the remaining items should be sorted by the "Name" key.

This is the initial JSON data:

var data = [
    {
        "id": "9",
        "title": "B"
    },
    {
        "id": "63",
        "title": "Z"
    },
    {
        "id": "433",
        "title": "D"
    },
    {
        "id": "50",
        "title": "A"
    },
    {
        "id": "2",
        "title": "G"
    }
]

Here is how I would like the final result to look:

var data = [
    {
        "id": "9",
        "title": "B"
    },
    {
        "id": "50",
        "title": "A"
    },
    {
        "id": "433",
        "title": "D"
    },
    {
        "id": "2",
        "title": "G"
    },
    {
        "id": "63",
        "title": "Z"
    }
]

Answer №1

To establish a custom sort order, consider using an object and assigning a default value to reposition other IDs towards the end.

var order = [3, 9, 50, 7],
    data = [{ id: "9", title: "B" }, { id: "63", title: "Z" }, { id: "433", title: "D" }, { id: "50", title: "A" }, { id: "2", title: "G" }],
    orderO = {};

order.forEach(function (a, i, aa) {
    orderO[a] = i - aa.length; // set negative values and zero as defaults
});

data.sort(function (a, b) {
    return (orderO[a.id] || 0) - (orderO[b.id] || 0) || a.title.localeCompare(b.title);
});

console.log(data);
console.log(orderO);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Answer №2

To begin, start by identifying the elements in your data array that correspond to those in your order array. Next, employ a specialized sorting algorithm to arrange the remaining elements and then combine the outcomes.

var order = [5, 11, 39, 8];
var data = [{ "id": "11", "title": "C" }, { "id": "72", "title": "W" }, { "id": "544", "title": "E" }, { "id": "39", "title": "R" }, { "id": "4", "title": "H" }];

function customSortArray(array, sortOrder) {
    var updatedArray = [];
    for (var j = 0; j < sortOrder.length; j++) {
        var position = array.findIndex(y => y.id === sortOrder[j].toString());
        if (position >= 0) {
            updatedArray.push(array.splice(position, 1));
        }
    }

    return updatedArray.concat(array.sort((x, y) => x.title > y.title ? 1 : -1));
}
console.log(customSortArray(data, order));

Answer №3

To streamline the order of your array, begin by reducing it to a single object where each element serves as a key with its index in the array as the corresponding value. Next, utilize sorting methods to arrange elements based on their presence in the array, followed by their position within the array, and lastly by title.

var data = [{"id":"9","title":"B"},{"id":"63","title":"Z"},{"id":"433","title":"D"},{"id":"50","title":"A"},{"id":"2","title":"G"}]

var order = [3,9,50,7].reduce(function(r, e, i) {
 return r[e] = i, r
}, {})

var result = data.sort(function(a, b) {
 return ((order[b.id] != undefined) - (order[a.id] != undefined) || (order[a.id] - order[b.id])) ||
  a.title.localeCompare(b.title)
})

console.log(result)

Answer №4

Give this a shot:

let order = [3,9,50,7];
let data = [
    {
        "id": "9",
        "title": "B"
    },
    {
        "id": "63",
        "title": "Z"
    },
    {
        "id": "433",
        "title": "D"
    },
    {
        "id": "50",
        "title": "A"
    },
    {
        "id": "2",
        "title": "G"
    }
]
     let sortedData =  data.sort((a, b) => {
          return ((order.indexOf(a.id) || Number.Max_VALUE) - (order.indexOf(b.id) || Number.MAX_VALUE) || a.title.localeCompare(b.title) )
        })
      console.log(sortedData)

Answer №5

Sorting can be accomplished with a single function by utilizing Array.indexOf to determine the order in which elements should be sorted. When there is only one item in the order array, it will always be prioritized first. In all other cases, sorting will be done alphabetically.

var order = [3,9,50,7];

var data = [
    {id: "9", title: "B"},
    {id: "63", title: "Z"},
    {id: "433", title: "D"},
    {id: "50", title: "A"},
    {id: "2",title: "G"},
    {id: "9",title: "F"},
    {id: "7",title: "D"},
    {id: "3",title: "E"},
    {id: "2",title: "F"},
]
// the sort function 
function sortFunc(a,b){
    var iA = order.indexOf(Number(a.id))+1; // get index of A
    var iB = order.indexOf(Number(b.id))+1; // get index of B
    if(iA && iB){  // if both in the order array
        return iA === iB ? // if the same in order array then sort alphabet
            a.title.localeCompare(b.title) :
            iA - iB;
    }
    // if A or B in order array move up else sort alphabet
    return iA ? -1 : iB ? 1 : a.title.localeCompare(b.title);
}
// sort data
data.sort(sortFunc);
// dispay result
data.forEach(obj=>console.log(obj.id + ":" + obj.title))

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

Discover the most helpful keyboard shortcuts for Next.js 13!

If you're working with a standard Next.js 13 app that doesn't have the experimental app directory, setting up keyboard shortcuts can be done like this: import { useCallback, useEffect } from 'react'; export default function App() { c ...

encountering an issue: file or directory does not exist, unable to open 'rds-combined-ca-bundle.pem'

I recently downloaded AWS secure socket for my Node server and integrated it into my index.js folder. However, I encountered an error that reads: "Error: ENOENT: no such file or directory, open 'rds-combined-ca-bundle.pem'. Could someone help me ...

What is the best way to display a date picker from a different page as a pop-up when a button is clicked on the current

Chapter One <button class="btn btn-outline-primary btn-sm btn-block " >Place order</button> Chapter Two <button class="simplepicker-btn" >Show Date Picker</button> > <script> > let simplepicker = new SimpleP ...

Incorporating React.js into HTML DOM Elements

As a beginner in react js, I'm facing an issue regarding DOM elements. Within my component, there is a table. When hovering over a cell, I want to highlight both the corresponding row and cell. Additionally, I need to obtain the coordinates of the hov ...

Ways to filter out specific fields when returning query results using Mongoose

I was wondering about the code snippet below: Post.create(req.body) .then(post => res.status(201).json(post)) .catch(err => res.status(500).json(err)) While this code works perfectly, I am curious about excluding a specific field, such as the __v fi ...

Is it possible to have both Node.js and browser code in the same file using webpack, while ensuring that only the browser code is accessible and the Node.js code remains hidden?

I need to work with a file that contains both Node.js and browser code. It's crucial that the Node.js code remains hidden when running in the browser environment. Is it possible for Webpack to exclude specific sections of the code based on the enviro ...

Discovering relevant information in a JSON file using user-input in Python

I have a JSON file located at this link: https://pastebin.com/2Z2DZ4Y6. My goal is to create a function that allows users to input search terms for tags and retrieve the corresponding gfyId from the JSON data. Although I've made some progress with the ...

Sorting by two fields with varying value types in AngularJS

Need help sorting json data by two fields, prioritizing field value and then date. Check out this demo Json input [{ "title" : "Title 2", "pin" : false, "date" : 20130411204207 },{ "title" : "Title 3", "date" : 20140411204207 },{ "title" : "Title 4", ...

Positioning a Three.js static CSS2DObject with respect to the camera's perspective

I am currently working on a unique program visualizer that utilizes Three.js to showcase various aspects of a program to the user. One crucial feature of this visualizer is allowing users to click on specific objects to view additional information about th ...

Repair the masthead background during overscroll

The Dilemma At the top of my webpage, I have a sleek masthead with a captivating background image that scrolls along with the page. However, there is an issue when users overscroll upwards, causing an undesirable white overflow to appear. To rectify this ...

Creating a layered effect by overlaying one image on top of another in an HTML5

Currently, I am facing an issue with drawing a level field inside my canvas. The images of the tank and enemies are being drawn underneath the field image, which is causing some problems as they should actually be moving above the field. Here is a link t ...

Buttons fail to function properly when inserted into Popover

I'm attempting to add 2 buttons to a popover triggered by the .clear-history button: <div class="modal-footer text-nowrap"> <button type="button" class="clear-history btn btn-link">Clear history</button> </div> const c ...

Ways to select a single checkbox when other checkboxes are selected in JavaScript

var select_all = document.getElementById("select_all"); //reference to select all checkbox var checkboxes = document.getElementsByName("testc"); //retrieving checkbox items //function to select all checkboxes select_all.addEventListener("change", function ...

Implementing a Unique Approach to Showcase the Initial PDF Page as Cover through Django and JS

I would like to enhance my script so that when a user hovers over an object on the template, a PDF cover page can be set for each object. Current process: Currently, I am able to upload files in the .pdf and .epub formats for each object with additional ...

The closing tag for the "body" element was excluded even though OMITTAG NO was specified

While attempting to validate my contact support page, I encountered the following errors: Omission of end tag for "body", even though OMITTAG NO was specified ✉ You may have forgotten to close an element or intended to self-close an element by ending ...

Guide to generating an array entry for every line of a text file in node.js

Struggling with converting each line of a text file into an array entry in node.js The array I am working with is named "temp." The code below successfully prints out each line: var temp = []; const readline = require('readline'); const fs = re ...

Embed fashion and graph elements into a CSV document (generated from <script>)

Encountering an issue with my code. I am looking to export an HTML table to a CSV file (specifically Libre Office Calc, regardless of csv, xls or xlsx format, as long as it runs on a Linux Server). Found a script online that works well after some modificat ...

Tips for ensuring that your website can recall which call-to-action (CTA) has been selected for redirection

I'm attempting to create a bilingual webpage in Spanish and English. My goal is to have a main page where the user selects the language, and once chosen, the page remembers the language preference for future visits instead of prompting the choice agai ...

Issue with getBytes not triggering .OnSuccess or .OnFailure events when using a onDataChange listener in Firebase

When running an addValueEventListener on my Firebase database triggered by a button click, a datasnapshot with user data is retrieved. This data is then processed in a for loop to save the data points into an SQLite database. The final step involves checki ...

Tips for blocking submissions when a user tries to input a hyperlink

I have encountered a problem in my journey of learning JS and unfortunately, I couldn't resolve it by myself. Lately, spam has been flooding through the form on my website and all my attempts with jQuery and JS to fix it have failed. As a last resort ...