Arrange objects in an array in a custom order

I received an array of objects from an API call that I need to organize into a specific format.

My goal is to sort the destination_country_id alphabetically, with the exception of the first three and last items. For example:

  1. "Ireland"
  2. "United Kingdom"
  3. "United States"
  4. ...other countries, in alphabetical order...
  5. "Everywhere Else"

I have thought about using array.sort(), which should help me alphabetize them easily. However, I am struggling to achieve the desired output so far.

API Response

[
    {
        "destination_country_id": null,
        "primary_cost": "9.50",
        "region_id": null,
        "destination_country_name": "Everywhere Else",
    },
    {
        "destination_country_id": 105,
        "primary_cost": "8.00",
        "region_id": null,
        "destination_country_name": "United Kingdom",
    },
    {
        "destination_country_id": 209,
        "primary_cost": "9.50",
        "region_id": null,
        "destination_country_name": "United States",
    },
    {
        "destination_country_id": 123,
        "primary_cost": "5.00",
        "region_id": null,
        "destination_country_name": "Ireland",
    },
    {
        "destination_country_id": 185,
        "primary_cost": "5.00",
        "region_id": null,
        "destination_country_name": "France",
    },
    {
        "destination_country_id": 145,
        "primary_cost": "5.00",
        "region_id": null,
        "destination_country_name": "Spain",
    }
]

Answer №1

This may not be the most efficient approach, but it is based on ES3 and does not rely on any external libraries. It is relatively easy to comprehend. This code snippet assumes that you want to sort alphabetically based on the destination_country_name attribute.

In JavaScript:

// where x represents your array of objects
x.sort(function (a, b) {
    return a.destination_country_name.localeCompare(b.destination_country_name);
}).sort(function (a, b) {
    return +(!b.destination_country_name.localeCompare('United States'));
}).sort(function (a, b) {
    return +(!b.destination_country_name.localeCompare('United Kingdom'));
}).sort(function (a, b) {
    return +(!b.destination_country_name.localeCompare('Ireland'));
}).sort(function (a, b) {
    return +(!a.destination_country_name.localeCompare('Everywhere Else'));
});

console.log(JSON.stringify(x, ['destination_country_name']));

Output:

function sorter(array, funcs, orders) {
    funcs = funcs || {};
    orders = orders || {};
    array.sort(funcs.general);
    
    if (Array.isArray(orders.top)) {
        orders.top.slice().reverse().forEach(function(value) {
            array.sort(funcs.top.bind(value));
        });
    }

    if (Array.isArray(orders.bottom)) {
        orders.bottom.forEach(function(value) {
            array.sort(funcs.bottom.bind(value));
        });
    }

    return array;
}

sorter(x, {
    general: function (a, b) {
        return a.destination_country_name.localeCompare(b.destination_country_name);
    },
    top: function (a, b) {
        return +(!b.destination_country_name.localeCompare(this));
    },
    bottom: function (a, b) {
        return +(!a.destination_country_name.localeCompare(this));
    }
}, {
    top: ['Ireland', 'United Kingdom', 'United States'],
    bottom: ['Everywhere Else']
});

View this on jsFiddle

With this method, you can easily sort based on different attributes by providing different comparison functions and specifying values that should appear at the top or bottom.

I have used ECMA5 methods here, but it can also be implemented with ECMA3.

Answer №2

In order to efficiently sort your array, one approach is to identify and remove the elements representing "Everywhere Else", "UK", "Ireland", and "US". Once these are eliminated, the remaining array can be sorted with ease. Despite sounding complex, this method is straightforward.

Check out this fiddle

var data = [
    {"destination_country_name": "Everywhere Else"},
    {"destination_country_name": "United Kingdom"},
    {"destination_country_name": "United States"},
    {"destination_country_name": "Ireland"},
    {"destination_country_name": "France"},
    {"destination_country_name": "Spain"}     ];
//other elements removed for clarity
var keep = ["Everywhere Else", "Ireland", "United Kingdom", "United States"];
var top = [];

for (var i = 0; i < keep.length; i++) {
    var index = function () {
        for (var j = 0; j < data.length; j++){    
            if (data[j].destination_country_name == keep[i])
                return data[j];    
        }
    }
    if (index > -1){        
        top.push(data[index]);    
        data.splice(index, 1);    
    }
}

data.sort(function (a, b) {    
    if (a.destination_country_name > b.destination_country_name)
        return 1;        
    if (a.destination_country_name < b.destination_country_name)
        return -1;        
    return 0;   
})

var sorted = top.concat(data), 
    extra = sorted.shift();    
    sorted.push(extra);        
console.log(sorted);

Alternatively, if you know those initial four places will always exist in the same order:

var data = [
    {"destination_country_name": "Everywhere Else"},
    {"destination_country_name": "United Kingdom"},
    {"destination_country_name": "United States"},
    {"destination_country_name": "Ireland"},
    {"destination_country_name": "France"},
    {"destination_country_name": "Spain"}     ];

var top = data.slice(0,4);
data.sort(function (a, b) {
    if (a.destination_country_name > b.destination_country_name)
        return 1;
    if (a.destination_country_name < b.destination_country_name)
        return -1;
    return 0;
})

var sorted = top.concat(data),
        extra = sorted.shift();
        sorted = sorted.push(extra);    

This method is more efficient and simpler as it eliminates the need to locate specific elements within the array.

Answer №3

If you want to organize objects in an array, you can assign a 'sort-order' property to each object. Specify the first three objects and the last one with known values, then give all other objects a value that is greater than the first three but less than the last one. Next, sort the array based on the sort-order and then alphabetically.

var arr= [{ "destination_country_id": null, "primary_cost": "9.50", "region_id": null, "destination_country_name": "Everywhere Else", },{ "destination_country_id": 105, "primary_cost": "8.00", "region_id": null, "destination_country_name": "United Kingdom", },{ "destination_country_id": 209, "primary_cost": "9.50", "region_id": null, "destination_country_name": "United States", },{ "destination_country_id": 123, "primary_cost": "5.00", "region_id": null, "destination_country_name": "Ireland", },{ "destination_country_id": 185, "primary_cost": "5.00", "region_id": null, "destination_country_name": "France", },{ "destination_country_id": 145, "primary_cost": "5.00", "region_id": null, "destination_country_name": "Spain", }]

var s= "destination_country_name",
order= ["Ireland", "United Kingdom", 
"United States", "Everywhere Else"];

arr.forEach(function(itm){
    var i= order.indexOf(itm[s]);
    if(i!= -1) itm.sort_order= i== 3? 1e50: i;
    else itm.sort_order= 10;
});

arr.sort(function(a, b){
    var d= a.sort_order- b.sort_order;
    if(d===0){
        if(a[s]=== b[s]) return 0;
        return a[s]>b[s]? 1: -1;
    }
    return d;
});
JSON.stringify(arr)
/*  returned value: (String)[{
        "destination_country_id": 123, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "Ireland", "sort_order": 0
    },{
        "destination_country_id": 105, "primary_cost": "8.00", "region_id": null, 
        "destination_country_name": "United Kingdom", "sort_order": 1
    },{
        "destination_country_id": 209, "primary_cost": "9.50", "region_id": null, 
        "destination_country_name": "United States", "sort_order": 2
    },{
        "destination_country_id": 185, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "France", "sort_order": 10
    },{
        "destination_country_id": 145, "primary_cost": "5.00", "region_id": null, 
        "destination_country_name": "Spain", "sort_order": 10
    },{
        "destination_country_id": null, "primary_cost": "9.50", "region_id": null, 
        "destination_country_name": "Everywhere Else", "sort_order": 1e+50
    }
]
*/

Answer №4

To organize the items in your given array named list, you have the flexibility to customize the sorting process by making use of this particular function call:

list.sort(function (elementA, elementB) {
    if (elementA.destination_country_name < elementB.destination_country_name) {
        return -1;
    }
    return 1;
});

Answer №5

If you want to sort an array using underscore's sortBy method:

var arr = [{name:'first3'},{name:'first2'},{name:'first1'},{name:'z'},{name:'m'},{name:'c'},{name:'end3'},{name:'end2'},{name:'end1'}]
arr = _.sortBy(arr, function (item,index){
    if (index <= 2) return String.fromCharCode(0);
    if(index >= arr.length - 3) return String.fromCharCode(255);
    return item.name;
})

console.log(JSON.stringify(arr))

[{"name":"first3"},{"name":"first2"},{"name":"first1"},{"name":"c"},{"name":"m"},{"name":"z"},{"name":"end3"},{"name":"end2"},{"name":"end1"}]

Check out this fiddle for more!

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

Validating Email Addresses and Passwords Using JavaScript

I have implemented a registration page where users can create accounts, and I am facing issues with the validation process. Specifically, I want to validate if the email is valid, if the two email fields match, if the password meets the length requirement, ...

Utilizing dynamic values for filtering within two nested Ng-repeat directives in AngularJS

For the second ng-repeat, I want to filter based on a dynamic value obtained from the first ng-repeat. Below is my code snippet: <div ng-repeat="all in all | unique: 'Category'"> <p>{{all.Category}}</p> <div class=" ...

The client side encountered an issue when attempting to transfer file data to a nodejs server

In my current project, I am working on a simple file upload module using AngularJS (v1.3.4) with a Node.js server. For this, I decided to utilize the https://github.com/danialfarid/angular-file-upload library. While the library seems straightforward, I hav ...

How can curly braces be utilized in an array reduce method?

If the function `fn3` is used instead of `fn2` in this code snippet running on node 9.5.0, the `console.log(totalUpvotes)` will display `undefined`. Shouldn't it actually be equal to 92? const posts = [{id: 1, upVotes: 2}, {id:2, upVotes: 89}, {id: ...

What is the best way to assign a value to a class variable within a method by referencing the 'this' keyword?

Is there a way to set the state of this Ionic react app when displaying the outcome of a reset service? I am facing challenges with using this.setState({resetSuccess}) within a method due to scope issues. (Details provided in comments) Here is the relevan ...

Using PHP to encode JSON and submit it via POST request

Issue: I am encountering difficulty in sending a JSON-encoded variable to a PHP page using jQuery/AJAX. Here is my current approach. The file is uploaded through It undergoes processing using jQuery based on the following JS code. JS code: <scrip ...

I wonder, what is Mongoose's isModified function actually verifying?

I have come across this specific isModified check frequently while researching, and even after reviewing Mongoose's documentation, I still struggle to grasp its precise purpose or significance. Initially, I considered the possibility that the check w ...

Is there a way to assign focus to an ASP.Net TextBox control using Javascript or code behind?

Trying to set the focus on a TextBox control within an UpdatePanel in an ASP.Net application (C#) has proven to be a challenge. Various attempts have been made, both in the code-behind and through JavaScript functions. tbxName.Focus(); Page.SetFocus(tbxNa ...

Paginating content without the need for a database

Seeking assistance on implementing pagination for displaying trading history API responses, without utilizing a database. Can anyone provide guidance and help with the necessary logic? Here is an excerpt of my code: <?php error_reporting(E_ALL) ...

How to make a dynamic array of objects in C++?

#include "resistor.h" void main() { srand(GetTickCount()); // Let's start by seeding the random number generator so that different runs of our program will always yield different results Resistor * pResistor; // Pointer to a resistor class ...

Ensure that you wait for all asynchronous $http requests to finish in AngularJS before continuing

I am facing a challenge with a page that generates a varying number of $http requests based on the length of a certain variable. I aim to update the scope with the data only after all requests have been completed. Without relying on jQuery for this project ...

Using Threejs with dropdown menus: Showcasing the chosen model exclusively

I am looking to only show the selected value (in this case, the 3D model) from a dropdown menu. The chosen option should be the only one visible in the camera view. I am encountering some difficulty with the following code segment: cons ...

How can I pass the dynamically generated ID from PHP to AJAX/jQuery using an anchor tag?

I'm seeking help with jQuery and Ajax as I am new to it. My issue is that I have multiple 'edit' buttons in a table, one for each row's data. When I click on an edit button to modify the data, they all open at once instead of just the s ...

Angular updating the parent model from within the transclude scope

I am puzzled by the concept of Angular transclude scope. I am attempting to create a collapsible directive, but it seems that binding inside the transclude scope does not affect the model of the parent unless I utilize an object like 'data'. < ...

Steps for adjusting the status of an interface key to required or optional in a dynamic manner

Imagine a scenario where there is a predefined type: interface Test { foo: number; bar?: { name: string; }; } const obj: Test; // The property 'bar' in the object 'obj' is currently optional Now consider a situatio ...

Having trouble connecting v-model to vue-date-picker

My experience with the vue-date-picker and v-model for two-way data binding has been interesting. Initially, I set the value to a date (referred as startDate in this case) and printed the passed value (i.e. startDate) in the console. The initial value pa ...

List of duplicated BLE devices detected in network scanning

Greetings! I am currently working on an Ionic project named BLE Scanner. After facing some challenges, I finally managed to connect to the devices. Below is the code snippet that I discovered online: home.ts (please ignore the DetailPage) import { Compon ...

Challenges with declarations and operators

Hi everyone, I'm trying to tweak the order of operators in a code snippet so that the result logged is 0. Can someone help me figure this out? numbers = [23, 12, 71, 10] operators = [ (a, b) => a + b, (a, b) => a / b, (a, b) => a * b, (a, b) ...

jQuery Form Plugin - fails to trigger error callback for Internal Server errors (500)

I am dealing with a situation where my server is returning a Status code 500, but my jQuery Form is triggering the success callback instead of the error callback. My current jQuery version is 1.7.1 and jQuery Form version is 2.73 from March 2011. The serv ...

Comparing jQuery and JavaScript: Which One is Right

I am familiar with JavaScript but not very experienced with jQuery. I have a function that needs to be executed within a jQuery $(document).ready(function() {} block. Can anyone guide me on how to incorporate this function into jQuery? function populate ...