Order an array based on a specified list of fields

Imagine you have an array of objects:

People = [
{ "id": 1, "name": Joseph, function: "preacher"},
{ "id": 2, "name": Ann, function: "singer"},
{ "id": 3, "name": Miles, function: "preacher"},
{ "id": 4, "name": Jack, function: "singer"},
{ "id": 5, "name": Igor, function: "secretary"}
];

Additionally, there is an array of properties:

sortingProperties = ['function', 'name'];

The task at hand is to sort the People array using a combination of properties specified in the sorting array. Here's how it can be achieved:

const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });

  People.sort(
    (x, y) =>
      (intlCollator.compare(x[sortingProperties[0]], y[sortingProperties[0]])) ||
      (intlCollator.compare(x[sortingProperties[1]], y[sortingProperties[1]])) 
    );

To make the sorting process dynamic and iterate through variable sort combinations, one might do the following:

sortingProperties = ['function', 'name'];

Or try this:

sortingProperties = ['name'];

Answer №1

One way to achieve the desired outcome is to loop through the keys of the objects until a comparison results in a non-falsy value.

const
    items = [{ id: 1, name: "Joseph", role: "leader" }, { id: 2, name: "Ann", role: "singer" }, { id: 3, name: "Miles", role: "leader" }, { id: 4, name: "Jack", role: "singer" }, { id: 5, name: "Igor", role: "assistant" }],
    intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' }),
    order = ['role', 'name'];

items.sort((a, b) => {
    let result;
    order.some(key => result = intlCollator.compare(a[key], b[key]));
    return result;
});
    
console.log(items);

Answer №2

Starting from ES10 sort has stability. This allows for sorting based on multiple keys in a sequential order.

const People = [
{ "id": 1, "name": "Joseph", function: "preacher"},
{ "id": 2, "name": "Ann", function: "singer"},
{ "id": 3, "name": "Miles", function: "preacher"},
{ "id": 4, "name": "Jack", function: "singer"},
{ "id": 5, "name": "Igor", function: "secretary"}
];

const criteria = ['name', 'function'];

const intlCollator = new Intl.Collator('pt-BR', { usage: 'sort' });
criteria.forEach(c => {
  People.sort((l, r) => intlCollator.compare(l[c], r[c]));
});

console.log(People);

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

Appears as though time is slipping away during date conversions

I seem to be experiencing a strange issue where I lose a day when transitioning between MySQL and my JavaScript code, and I can't seem to figure out why. When I insert a date into the database (for example, 10/14/12), it appears as 10/13/12 in the dat ...

Universal Module Identifier

I'm trying to figure out how to add a namespace declaration to my JavaScript bundle. My typescript class is located in myclass.ts export class MyClass{ ... } I am using this class in other files as well export {MyClass} from "myclass" ... let a: M ...

Angular: Implementing ngIf within ngFor for Dynamic Content Display

I'm working on dynamically populating a list with conditional rendering for each list item, where the condition can be changed by user input. For instance: app.component.ts private check = true; private some = [ {name: 'ABC', cond ...

The function .load callback was triggered on five separate occasions

I'm currently working with the code below and I have a feeling that I'm overlooking something important but just can't seem to figure it out. Basically, when the user clicks a button, a fragment of the page is loaded. Once this loading is s ...

What is the process of sending a component as props using props in react?

Currently, I am utilizing the react-grid library provided by dev-express. Within this library, there is a Table component that allows us to pass in a Cell component. In my CustomCell component, I have integrated the Menu component from Material UI. < ...

Utilizing jQuery and JSON to showcase the contents of an array

My goal is to display all the items in an array by utilizing JSON and jQuery from the Song of Ice and Fire API. Currently, I am only able to display one item from each of the arrays. If you want to view the codepen, click here: https://codepen.io/frederic ...

What could be the reason for the three.js scene failing to render in my Svelte application?

Scene.svelte <!-- Start by binding a container, then add the renderer to this container onMount --> <script> import { onMount } from 'svelte'; import * as THREE from 'three'; let container; onMount(async () = ...

Is there a way to trigger a function after a tooltip or popover is generated using Twitter Bootstrap?

Is there a way to manipulate a tooltip or popover with twitter bootstrap after it has been created? It seems like there isn't a built-in method for this. $('#selector').popover({ placement: 'bottom' }); For instance, what if I ...

Tips for concealing a Div element in Angular 4 using webApi

In my Angular 4 web application, I'm looking for a way to display an image if it exists at a certain file location, and if not, I want to show an empty space. Can someone please help me with a solution? Here is my Component.html file: <div cla ...

Problem integrating multer with Express JS and Node JS

Click here to access the server.js file on GitHub Following a tutorial, I have implemented code accordingly. However, when working with an updated version of Express JS, errors are being thrown on the side of Express JS. Error C:\nodefiles&bso ...

Excessive whitespace appearing on the right and bottom edges of the Angular application

I'm fairly new to web development, so this may be a silly question, but I really could use some help. I've created my first Angular app and noticed that there is a lot of white space on the right side of the landing page, as well as at the bottom ...

Is it possible to modify a single value in a React useState holding an object while assigning a new value to the others?

In my current state, I have the following setup: const [clickColumn, setClickColumn] = useState({ name: 0, tasks: 0, partner: 0, riskFactor: 0, legalForm: 0, foundationYear: 0 }) Consider this scenario where I only want to update ...

Leveraging AngularJS $filter in conjunction with ng-disabled

I have a variable in my $scope that contains information about an election, including a list of voters with unique IDs: $scope.election = { voters: [ { _id: '123' }, { _id: '456' }, { _id: '789' } ] } Additio ...

What are the best ways to improve ajax response in jQuery?

My database query is fetching around 5000 rows of data along with data from 5 relational tables, leading to performance issues. The network tab shows the size of the request resource as 9.1 mb. After that, I am dynamically adding this data to a table using ...

JQuery Anchor Link Scrolling Problem on Specific Devices

I'm having an issue where my webpage does not scroll correctly to an anchor when a link is clicked. The problem arises from the header size changing based on the viewport width. While it works fine in desktop Chrome, in the mobile version the header h ...

What is the best way to organize a massive file over 10Gb filled with words?

I've been presented with this interview query: You have an input file containing words (which could be a jumble of letters) separated by commas, and the file size is 10 GB or more. Can you devise an algorithm to sort all these words? Keep in min ...

Utilizing variables in GraphQL requests

UPDATE: see the working code below GraphiQL Query I have this query for retrieving a gatsby-image: query getImages($fileName: String) { landscape: file(relativePath: {eq: $fileName}) { childImageSharp { fluid(maxWidth: 1000) { base64 ...

Having trouble loading JavaScript in my Django and React Project using Vite.js - need some help!

After creating a project with React as the frontend and Django as the backend, I organized them into separate folders: backend and frontends (please disregard the deliberate spelling mistake). To build the React project, I utilized vite.js and then genera ...

How can I implement a button in Angular Ag Grid to delete a row in a cell render

I have included a button within a cell that I want to function as a row deleter. Upon clicking, it should remove the respective row of data and update the grid accordingly. Check out the recreation here:https://stackblitz.com/edit/row-delete-angular-btn-c ...

Issues with PHP not reflecting changes to MySQL database

I'm struggling to find a solution to the issue I'm facing on various forums. The problem involves two pages, an HTML page and a PHP page. The HTML page simply populates a dropdown list from a database column. Below is a simplified version of the ...