Arrange the array based on the key values

I am currently working with a function that sorts by name and an array containing value/key pairs.

I am trying to figure out how I can dynamically pass the key on which the sort is being performed, so that I can call the same function each time with different keys:

var arr = [{name:'bob', artist:'rudy'},
           {name:'johhny', artist:'drusko'},
           {name:'tiff', artist:'needell'},
           {name:'top', artist:'gear'}];

sort(arr, 'name');   //sort by name
sort(arr, 'artist'); //sort by artist

function sort(arr) {
  arr.sort(function(a, b) {
    var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
    if (nameA < nameB) //sort string ascending
      return -1;
    if (nameA > nameB)
      return 1;
    return 0; //default return value (no sorting)
   });          
}

Answer №1

CustomArray.prototype.sortByKey = function(key){
    this.sort(function(x, y){
        if(x[key] < y[key]){
            return -1;
        }else if(x[key] > y[key]){
            return 1;
        }
        return 0;
    });
}

var customArr = [{name:'Alice', age:32},{name:'Bob', age:25},{name:'Eve', age:40},{name:'Charlie', age:30}];

customArr.sortByKey("name");
customArr.sortByKey("age");

Answer №2

[updated on 2020/08/14] This answer has been revised and simplified due to its outdated nature and lack of quality.

Develop a function that generates a sorting lambda (the callback for Array.prototype.sort that handles the sorting logic). This function should accept parameters such as the key name, the type of sorting (string - case sensitive or not, or numeric), and the sorting order (ascending or descending). The lambda utilizes the provided parameter values (closure) to determine the sorting mechanism.

const log = (...strs) => 
  document.querySelector("pre").textContent += `\n${strs.join("\n")}`;
const showSortedValues = (arr, key) => 
  ` => ${arr.reduce((acc, val) => ([...acc, val[key]]), [])}`;
  
// function to create sort lambda based on key, type, and order
const sortOnKey = (key, string, desc) => {
  const caseInsensitive = string && string === "CI";
  return (a, b) => {
    a = caseInsensitive ? a[key].toLowerCase() : a[key];
    b = caseInsensitive ? b[key].toLowerCase() : b[key];
    if (string) {
      return desc ? b.localeCompare(a) : a.localeCompare(b);
    }
    return desc ? b - a : a - b;
  }
};

// a few examples of sorting
const onNameStringAscendingCaseSensitive = 
  getTestArray().sort( sortOnKey("name", true) );
const onNameStringAscendingCaseInsensitive = 
  getTestArray().sort( sortOnKey("name", "CI", true) );
const onValueNumericDescending = 
  getTestArray().sort( sortOnKey("value", false, true) );

// display sorted values
log(`*key = name, string ascending case sensitive`,
  showSortedValues(onNameStringAscendingCaseSensitive, "name")
);

log(`\n*key = name, string descending case insensitive`,
  showSortedValues(onNameStringAscendingCaseInsensitive, "name")
);

log(`\n*key = value, numeric desc`, 
  showSortedValues(onValueNumericDescending, "value")
);

function getTestArray() {
  return [{
    name: 'Bob',
    artist: 'Rudy',
    value: 23,
  }, {
    name: 'John',
    artist: 'Drusko',
    value: 123,
  }, {
    name: 'Tiff',
    artist: 'Needell',
    value: 1123,
  }, {
    name: 'Top',
    artist: 'Gear',
    value: 11123,
  }, {
    name: 'john',
    artist: 'Johanson',
    value: 12,
  }, ];
}
<pre></pre>

Answer №3

const sortByKey = (key) => {
  return function(a,b) {
    if (a[key] > b[key]) return 1;
    if (a[key] < b[key]) return -1;
    return 0;
  }
}

arrayOfItems.sort(sortByKey('name'));

Answer №4

Simplify your daily tasks by implementing a closure

Check out a live example here

var filter = 'name', //sort by name
data = [{name:'bob', artist:'rudy'},{name:'johhny', artist:'drusko'},{name:'tiff', artist:'needell'},{name:'top', artist:'gear'}];; 

var compare = function (filter) {
    return function (a,b) { //closure
        var a = a[filter],
            b = b[filter];

        if (a < b) {
            return -1;
        }else if (a > b) {
            return 1;
        } else {
            return 0;
        }
    };
};

filter = compare(filter); //set filter

console.log(data.sort(filter));

Answer №5

After reviewing all the solutions provided, I devised my own approach that is compatible across various browsers. The solution that was originally accepted does not function properly in Internet Explorer or Safari. Additionally, the other proposed solutions do not support sorting in descending order.

/*! FUNCTION: ARRAY.KEYSORT(); **/
Array.prototype.keySort = function(key, desc){
  this.sort(function(a, b) {
    var result = desc ? (a[key] < b[key]) : (a[key] > b[key]);
    return result ? 1 : -1;
  });
  return this;
}

var arr = [{name:'bob', artist:'rudy'}, {name:'johhny', artist:'drusko'}, {name:'tiff', artist:'needell'}, {name:'top', artist:'gear'}];
arr.keySort('artist');
arr.keySort('artist', true);

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

Troubleshooting Problem with Padding in ion-content for Ionic Angular

I am currently developing my inaugural Ionic application. The initial template I utilized was the rudimentary sidemenu layout. $ ionic start myApp sidemenu Afterwards, I crafted a straightforward page featuring a list which appears as follows... <ion ...

What's the quickest method for duplicating an array?

What is the quickest method for duplicating an array? I wanted to create a game, but I found that Array.filter was performing too slowly, so I developed a new function: Array.prototype.removeIf = function(condition: Function): any[] { var copy: any[] ...

Select a picture at random from a directory

As a student embarking on an art project, I am in the process of selecting one out of 500 images to display on a webpage. My coding knowledge is quite limited, primarily focused on HTML and CSS, with only a basic understanding of JavaScript. I am encounter ...

Issue with nextJS/Firebase database while experimenting with enabling web frameworks

I encountered an issue with a nextJS app I built on Firebase, following the steps and running the commands mentioned below: % npx create-next-app@latest % cd myapp % firebase experiments:enable webframeworks % npm install -g firebase-tools % firebase ...

The TransferList component in Material UI does not update its state based on props when using the useState

My TransferList component in Material UI receives an array of previously selected items as props.selectedItems. The props.Items contains all available items. I expected to see props.selectedItems in the left panel of TransferList, but the left panel is em ...

Are the loops malfunctioning or is it a problem with the array?

I am currently tackling the challenges of Project Euler problem 11 and have hit a roadblock during my testing. Instead of using a text document as input, I am working with numbers from 1 to 400. However, when running the program, the calculated result is ...

Iterate over the array elements in React by using Hooks on click

I am facing an issue with loading objects separately from a JSON file when a button is clicked. The problem occurs when the index goes out of bounds, resulting in a TypeError "Cannot read property 'content' of undefined" message. I have tried u ...

How can we efficiently determine if any of the keys in an array of objects contains a value that is present in another array of arrays object?

I am working on developing a filtering system that checks for the existence of project technologies in the arrOfObjs.name. If a match is found, then the filter will allow the project to be displayed in the DOM. This filter specifically involves using a com ...

Exploring the world of mocking and stubbing in protractor

I am interested in testing my angular application using protractor. The app includes an API Module that communicates with the server In these tests, I would like to mock this API Module. I am not looking to perform full integration tests, but rather tests ...

Using D3.js to plot data points on a topojson map's coordinates

Having difficulty converting latitude and longitude coordinates to "cx" and "cy" positions on my SVG map created with d3 and topojson. Despite researching solutions online, I am unable to successfully implement the conversion process. Each time I try to co ...

Tips for unit testing an Angular Service that is primarily responsible for redirecting to an external page from the application

My service is responsible for redirecting to a separate login page since we are implementing login as a service. function redirectToMembership() { var returnURL = $location.host(); returnURL+="/#/Authorization"; $window.location.href=Environme ...

Unable to add key/value pair to object in Node

While using Node, I encountered a strange issue where I was unable to attach the key/value pair broadcastStamp = date to the object "result." Despite confirming that it is indeed an object with typeof, no errors were thrown - the key/value simply did not a ...

Tips for maintaining consistent header and footer while developing the front end using JavaScript

Is it possible to maintain the same header and footer on all pages of a website if using JavaScript for the front end and PHP for the back end? While I am comfortable doing this with PHP, I am curious if it can also be achieved with JavaScript or HTML, o ...

Passing PHP Variables Between Pages

I'm currently working on building a game using html5(phaser js) and I need to create a leaderboard. Here's the code snippet I have: restart_game: function() { // Start the 'main' state, which restarts the game //this.game.time.events ...

What is the best way to bypass array values in PHP?

Seeking assistance with an array: Array ( [0] => 2 [1] => 2 [2] => 1 [3] => 1 [4] => 2 [5] => 2 ) Exploring the use of a foreach loop: foreach( $valortot as $key => $m ) { $valortot[$key]; echo $valortot[$key]; echo "<br>"; } T ...

Sticky box fails to maintain position as header scrolls

I am looking to create a Sidebar that sticks to the window while scrolling, but stops when it reaches the footer. I have managed to get it partially working, but there is a small issue that I can't seem to solve. Test it live here: Everything seems ...

How to download a file using AJAX in Laravel?

Is there a way to download a CSV file within an ajax call? I have an ajax request in my Laravel controller that successfully retrieves the file contents in the response. However, I am facing issues with actually downloading the file. Laravel controller c ...

Retrieving information from an unfamiliar encoding document

Our testing equipment, manufactured in 1995, is powered by MS DOS. The Analog-digital converter records information in a file. In [picture1] the structure of the file is revealed. [Picture2] displays the oscillogram that was created using data from the fil ...

How to Use Discord.js v13 to Make an Announcement in a Specific Channel

Looking for a Solution I am trying to create a command that allows an admin user to send a specific message to a designated channel. The Issue at Hand My current approach involves sending a response back to the user who triggered the command with the ent ...

The default zoom setting for ng-map is overly magnified when paired with the zoom-to-include-markers="true" feature

When using maps, I encountered an issue where having only one marker with the zoom-to-include-markers="true" attribute resulted in the map being overly zoomed in. Regardless of how I adjusted the zoom attribute, the result looked like this: https://i.sstat ...