Eliminate redundant elements during the process of arranging an array

I have a collection of objects in an array that needs to be sorted and have duplicates removed based on specific values within each object. Currently, I am using two separate loops (not nested) - one for sorting and another for removing duplicates. Is there a more efficient way to accomplish this task? The current code is slow when dealing with thousands of items:

var list = [
    {a: "Somename", b: "b", c: 10},
    {a: "Anothername", b: "a", c: 12},
    // more objects...
];
function sortAndRemoveDuplicates(list) {
    // Sort the list based on the specified values
    list = list.sort(function(a,b) {
        a.a = a.a.toLowerCase();
        b.a = b.a.toLowerCase();
        if (a.a < b.a) return -1;
        if (a.a > b.a) return 1;

        a.b = a.b.toLowerCase();
        b.b = b.b.toLowerCase();
        if (a.b < b.b) return -1;
        if (a.b > b.b) return 1;

        if (a.c < b.c) return -1;
        if (a.c > b.c) return 1;

        return 0;
    });

    // Loop through the list to remove duplicates
    for (var a,b,i=list.length-1; i > 0; i--) {
        a = list[i];
        a.a = a.a.toLowerCase();
        a.b = a.b.toLowerCase();

        b = list[i-1];
        b.a = b.a.toLowerCase();
        b.b = b.b.toLowerCase();

        if (a.a === b.a && a.b === b.b && a.c === b.c) list.splice(i-1,1);
    }

    return list;
}
list = sortAndRemoveDuplicates(list);

Please refrain from suggesting jQuery solutions or the use of additional libraries. It seems unnecessary to import a library for such a simple task.

Answer №1

To optimize the code in your second loop, consider simply adding unique values to a new array instead of using splice. This way, instead of removing elements from the original array with splice, you can directly add values to the new array using push. The performance of push is generally better than that of splice. Here's an example:

var uniqueList = [];
if (list) {
    uniqueList.push(list[0];
    for (var current, previous, i=1; i < list.length; i++) {
        current = list[i];
        current.property1 = current.property1.toLowerCase();
        current.property2 = current.property2.toLowerCase();

        previous = list[i-1];
        previous.property1 = previous.property1.toLowerCase();
        previous.property2 = previous.property2.toLowerCase();

        if (current.property1 !== previous.property1 || current.property2 !== previous.property2 && current.property3 !== previous.property3) {
            uniqueList.push(current);
        }
    }
}

Answer №2

Through my exploration, I devised a unique solution. By utilizing two loops in a more efficient manner, I was able to achieve faster results compared to the traditional method of sorting and removing duplicates. Instead of tracking duplicates during sorting, I looped through the array and stored each item in an object using a concatenation of the property values ('key') that I wanted to sort and remove duplicates by. If the key was already present, it indicated a duplicate which could be skipped. Otherwise, the item was added to a new array. Once duplicates were eliminated, I proceeded to sort the array before returning it:

function customSort(list){
    // The three properties for sorting can be converted to strings. By iterating
    // through the given array, I concatenated those property values to create 'keys'
    // and stored them in a temporary object. Duplicate detection was based on
    // the presence of these 'keys' in the temporary object.
    for (var a=0,b=list.length,item,key="",dupObj={},nList=[]; a<b; a++) {
        item=list[a];
        key=item.a.toLowerCase()+"_"+item.b.toLowerCase()+"_"+item.c;
        if(!dupObj[key]) {
            dupObj[key]=true;
            nList.push(item);
        }
    }

    // After removing duplicates, the array is sorted:
    nList.sort(function(a,b) {
        if ((a.a = a.a.toLowerCase()) < (b.a = b.a.toLowerCase()) return -1;
        if (a.a > b.a) return 1;

        if ((a.b = a.b.toLowerCase()) < (b.b = b.b.toLowerCase())) return -1;
        if (a.b > b.b) return 1;

        if (a.c < b.c) return -1;
        if (a.c > b.c) return 1;

        return 0;
    });

    // Return the updated list
    return nList;
}
var list = [
    {a: "Somename", b: "b", c: 10},
    {a: "Anothername", b: "a", c: 12},
    // Further entries
];
list = customSort(list);

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

Ways to personalize Angular's toaster notifications

I am currently utilizing angular-file-upload for batch file uploads, where I match file names to properties in a database. The structure of the files should follow this format: 01-1998 VRF RD678.pdf VRF represents the pipeline name RD represents the lo ...

Is it possible for PHP to process a multidimensional array being submitted via $_POST along with another field serving as a key in the same form

My web form includes two select fields: "user_id[]" and "equipment_id[]. Here are some key points: I use a Javascript function to duplicate the group of "user_id[]" and "equipment_id[] fields each time I want to add another set. The "user_id[]" field all ...

Issue with Jquery function not executing on second attempt

/** Creates a table of iTunes data in HTML format **/ var appendValues = function(songArray) { songArray.each(function() { var title = $(this).find("im\\:name").eq(0).text(); var songImage = $(this).find("im\\:image").eq(0).text(); var ...

Ways to retrieve the ID of the clicked element from the child up to the parent

I currently have a Parent component and a Child component. The Child component contains inner elements called notes, with "delete" being one of them. My goal is to have the Child component return an ID to the Parent component when the delete element is cl ...

Monitor the output of a spawned process that is currently in a state of awaiting user input

In my Swift program, I am logging information to the stdout while waiting for a termination signal of \n. The input is requested immediately upon starting and the info is logged 1~2 seconds later: fetchAndLogDataInBackground(); // will print some dat ...

Can we integrate the Node.js API into Meteor?

Being new to Meteor.js, I've been wondering if it's possible to utilize the node API in my project. I've hit a roadblock and haven't been able to find any information on this topic despite spending a significant amount of time researchi ...

What is the best way to initiate an ajax asynchronous call following the getCurrentPosition callback?

I used the browser's Navigator getCurrentPosition to obtain my current location. Within the callback function of getCurrentPosition, I am attempting to retrieve the address based on latitude and longitude coordinates. The only thing I am able to fetch ...

Learning how to extract data from a JSON file using JavaScript

One of the challenges I'm facing involves a JSON file that looks like this: { "residents": [ { "name" : "Jacob", "title" : "King", "gender" : "Male", }, { "name" : "Luthor", ...

The art of selecting elements and attaching event listeners in a React environment

Currently, I am working on my portfolio website using Gatsby. The layout includes a sidebar on the left with navigational links (Home, About, Work, etc.), and the main content is displayed as one long strip of sections on the right. When a user clicks on a ...

Display elements on the side of the page using jQuery as the user scrolls

I'm in search of a helpful jQuery plugin that I can't quite put a name to! Can anyone point me in the right direction? Take a look at this website for inspiration: On that page, you'll notice that as you scroll down, elements smoothly appe ...

A guide to traversing a class and pinpointing each element that contains a particular classlist property

Here is my code snippet that generates 4 spans within a class. When a user clicks on a span, it changes color to indicate that it has been clicked. <head> <style> .tagger1010 span { padding: 6px 10px; ...

What sets apart toBeInTheDocument from getBy* in @testing-library/react?

Can you distinguish between these two methods in react-testing-library? expect(screen.queryByText('<something>')).toBeInTheDocument(); And screen.getByText('<something>'); (The specific getBy* and queryBy* operation are no ...

How do I select all checkboxes in TypeScript when I only click on one of them?

I'm currently working with a list of checkboxes in my HTML code: <div class="col-sm-12" *ngIf="ControllerModel"> <div *ngFor="let controller of ControllerModel" class="panel col-md-6 col-lg-6 col-xs-6"> <div class="panel-heading" ...

What is the best way to display the current time (generated through JavaScript) within a designated div element?

During my JavaScript studies, I stumbled upon the following code snippet: function printTime() { var d = new Date(); var hours = d.getHours(); var mins = d.getMinutes(); var secs = d.getSeconds(); document.body.innerHTML = hours+":"+mins+":"+sec ...

Troubleshooting problem with saving/displaying certain characteristics in HttpSession, array in Servlets

I am just starting out with servlets and JDBC and I need some assistance with the code below: try{ String selectSQL = "select * from product_list where category = '"+category+"'"; Statement stmt = conn.createStatement(); ...

Add information to the database using JavaScript within the ASP.NET C# framework. Once the data has been successfully inserted into the database, I aim to display an alert

Is it possible to use JavaScript to insert data into a database in an ASP.NET C# environment? If so, after successfully inserting the data, how can an alert box be created? ...

perform an action if any division element is void of content

Currently, I have a statement that checks if any of the Divs with the ID #Drop are empty. If one is found to be empty, an alert is shown. However, there seems to be an issue where the statement stops working when any div contains content. What I am trying ...

Is JavaScript asynchronous when it comes to manipulating the DOM?

While conducting Javascript tests on the Android browser, I monitored the number of instruction counts executed on the CPU. The test code for JS is straightforward and embedded within HTML files located in the local directory of an Android device, not on a ...

Using AngularJS to iterate through a nested array with ng-repeat

Hey everyone, I've been working on a project where I have an array called menu[] with nested arrays called flavors[] within it. My goal is to calculate the total price of all active items and flavors in the menu. While I was able to successfully calcu ...

Why isn't the AngularJS injected view resizing to fit the container?

As a novice delving into a project in the MEAN stack, I'm encountering inconsistent HTML previews. When I view it independently versus running it from the project, the display varies. Here's the intended appearance (in standalone preview): imgu ...