Arranging an array containing three elements

As I work on my angular app, I have come across the following array:

[
 {
        "Name": "Jack",
        "IncomingTime": "2020-06-19T11:02+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  {
        "Name": "Mary",
        "IncomingTime": "2020-06-19T11:05+00:00",
        "Outgoingtime": "2020-06-19T11:07+00:00",
  },
  ...
]

My goal is to create a unique sorted array based on certain criteria. First, I want to sort the elements alphabetically by Name. Then, if names are the same, I want to further sort them by Incoming time. For example, duplicates of a name with the same incoming and outgoing times should be discarded except for the earliest incoming time entry. In cases where all attributes (Name, IncomingTime, OutgoingTime) are the same, only the entry with the earliest Outgoing time should remain in the resulting array. How can I achieve this sorting algorithm?

Answer №1

Considering the original data you provided,

const rawData = [
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:02+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Mary",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "jolly", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", },
  { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:17+00:00", },
  { "Name": "Maria", "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T12:53+00:00", },
  { "Name": "Jack",  "IncomingTime": "2020-06-19T11:05+00:00", "Outgoingtime": "2020-06-19T11:07+00:00", }
];

To achieve your desired output, we follow these steps:

  • Initially, we arrange the raw data based on Name, then IncomingTime, and finally by OutgoingTime.

  • Next, we loop through the sorted data and keep track of the previous item visited. When a change in the primary sort key (a name difference) is observed, it indicates the desired item (e.g., the record for the specific name with the earliest incoming time), which is then added to the set of unique items. A sequence break occurs when:

    1. No previous item exists, indicating the first item in the list.
    2. The Names of the current and previous items are different.

This results in the following solution.

const sortedData = rawData.sort(
  (x,y) => x.Name         < y.Name         ? -1 // sort by name
         : x.Name         > y.Name         ? +1 //
         : x.IncomingTime < y.IncomingTime ? -1 // followed by incoming time
         : x.IncomingTime > y.IncomingTime ? +1 //
         : x.Outgoingtime < y.Outgoingtime ? -1 // and outgoing time
         : x.Outgoingtime > y.Outgoingtime ? +1
         :                                    0 // both items compare equal
);
const uniqueData = [];
let prev;
for (const curr of sortedData) {
  if ( !prev || curr.Name !== prev.Name ) {
    uniqueData.push(curr);
  }
  prev = curr;
}
console.log(JSON.stringify(uniqueData,undefined,2));

This code snippet outputs:

[
  {
    "Name": "Jack",
    "IncomingTime": "2020-06-19T11:02+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  },
  {
    "Name": "Maria",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:17+00:00"
  },
  {
    "Name": "Mary",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  },
  {
    "Name": "jolly",
    "IncomingTime": "2020-06-19T11:05+00:00",
    "Outgoingtime": "2020-06-19T11:07+00:00"
  }
]

An alternative approach using Map can simplify this process while retaining the order of the sorted list:

const sortedData = rawData.sort(
  (x,y) => x.Name         < y.Name         ? -1 // sort by name
         : x.Name         > y.Name         ? +1 //
         : x.IncomingTime < y.IncomingTime ? -1 // followed by incoming time
         : x.IncomingTime > y.IncomingTime ? +1 //
         : x.Outgoingtime < y.Outgoingtime ? -1 // and outgoing time
         : x.Outgoingtime > y.Outgoingtime ? +1
         :                                    0 
);

const map = new Map();
for (const entry of sortedData) {
  const value = map.get(entry.Name);
  if (!value) {
    map.set(entry.Name, entry);
  }
}

const uniqueData = Array.from(map.values());

Answer №2

Not entirely certain, but perhaps something along these lines...

aa.sort(
    function (a, b) {

        // attempting to sort by names
        if (a["Name"] < b["Name"])
            return -1;
        else if (a["Name"] > b["Name"])
            return 1;

        // if names are the same, then compare IncomingTime
        if (a["IncomingTime"] < b["IncomingTime"])
            return -1;
        else if (a["IncomingTime"] > b["IncomingTime"])
            return 1;



        return 0;
    }
);

Answer №3

If you want to easily sort a collection by multiple criteria, consider using the lodash library and its sortBy function.

import * as _ from 'lodash'

let sorted_collection = _.sortBy(collection, ['Name', 'IncomingTime', 'Outgoingtime'])

The _.sortBy function allows you to apply multiple level sorting efficiently. Give it a try!

Answer №4

When looking at TypeScript, the implementation by Mayank Gupta appears as follows:

a.sort((a:any, b:any) => a.Name>b.Name?1:a.Name<b.Name?-1:
                       a.IncomingTime>b.IncomingTime?1: a.IncomingTime<b.IncomingTime?-1:
                       a.Outgoingtime>b.Outgoingtime?1:
                       a.Outgoingtime<b.Outgoingtime?-1:0)

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

Difficulty comprehending the response from an AJAX post is being experienced

I'm currently working on a website and facing an issue connecting JavaScript with PHP using AJAX. Specifically, I'm struggling with reading the AJAX response. My PHP script contains the following code: <?php echo "1"; In addition, I have a ...

Am I on the right track with incorporating responsiveness in my React development practices?

Seeking advice on creating a responsive page with React components. I am currently using window.matchMedia to match media queries and re-rendering every time the window size is set or changes. function reportWindowSize() { let isPhone = window.matchMed ...

Getting the value of elements with the same id in JavaScript can be achieved by utilizing the getElement

When I click on the first delete link, I want to display the value from the first input box. Similarly, when I click on the second delete link, I want to show the value from the second input box. Currently, it is always showing the value from the first del ...

Exploring an array in React using typescript

I have a persistent data structure that I'm serving from the API route of my Next.js project. It consists of an array of objects with the following properties: export interface Case { id: string; title: string; participants: string[]; courtDat ...

Is Angular capable of determining which module to load for the frontend, or does it always need to load the entire application with all modules?

Is it possible for Angular 2 to selectively load specific modules for the frontend, or does it always have to load the entire application with all modules included? ...

What is the best way to implement a modal that can toggle dark mode using the Konami code, with the added functionality of a close button?

Recently, I attempted to create a Modal window that would activate when the Konami code (↑↑↓↓←→←→BA) is typed. As someone new to JavaScript, I'm still learning and open to feedback. While I have the coding part figured out, I need assi ...

I am looking to create a unique JavaScript variable within my GTM container that will automatically return a value of true when the user approves sharing

Is there a way to trigger a tag when the user shares their location with the browser? I attempted using the following code within a custom JavaScript variable in my GTM Container, but it didn't seem to work. navigator.permissions && navigator ...

Discover the steps to download web page data using Objective-C while ensuring that JavaScript has finished executing

I attempted something similar: NSString *url = @"http://www.example.com"; NSURL *urlRequest = [NSURL URLWithString:url]; NSError *error = nil; NSString *htmlContent = [NSString stringWithContentsOfURL:urlrequest encoding:NSUTF8StringEncoding error:&e ...

Form for creating and updating users with a variety of input options, powered by Angular 2+

As I work on creating a form, I encounter the need to distinguish between two scenarios. If the user selects 'create a user', the password inputs should be displayed. On the other hand, if the user chooses to edit a user, then the password inputs ...

Link rows to dictionary keys and show their corresponding values

In my React component, I have a list of dictionaries stored in the props as follows: console.log(fruits): [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…} ] The dictionary entries are: 0: name: 'Apple' color: 'Red&apos ...

Efficient method for handling numerous AJAX requests

I have a web application that currently makes 14-15 AJAX calls to various APIs. The issue is that the combined time it takes for all the AJAX calls to complete is significantly longer than when I individually type each API's URL into the browser. Cur ...

Incorporating a React element into a JavaScript object's property: A comprehensive guide

Below is a React Element named Info that has been attached to a Javascript object named myObj: let Info = ( <Info type="green" /> ); let myObj = { ReactComp: Info }; Now, the goal is to render the Info component using the above myObj objec ...

Assigning a specific data type value to an element as it enters the top of the viewport

I have a unique color code stored for each section, and when a section reaches the top of the screen (specifically -180px for the header), I want to dynamically change the text color of the header element as you scroll through the sections. Despite no erro ...

The URL provided for the Ajax HTTP request is not accurate

Consider the following JavaScript code: <script type="text/javascript" charset="utf-8> function goForLogin() { var xmlhttp; xmlhttp=new XMLHttpRequest(); xmlhttp.open("POST","/account/login",true); xmlhttp.s ...

Adjust the template within a directive to dynamically include an additional directive

Challenge Create a custom directive that dynamically adds the ng-bind attribute, allowing for the use of ng-bind, ng-bind-html, or ng-bind-html-unsafe without needing to manually add it to the template definition throughout. Illustrative Example http://j ...

Unable to load class; unsure of origin for class labeled as 'cached'

Working on an Angular 10 project in visual studio code, I've encountered a strange issue. In the /app/_model/ folder, I have classes 'a', 'b', and 'c'. When running the application in MS Edge, I noticed that only classes ...

Tips for executing an npm command within a C# class library

I am currently developing a project in a class library. The main objective of this project is to execute a JavaScript project using an npm command through a method call in C#. The npm command to run the JavaScript project is: npm start The JavaScript ...

The React.js .map function encountered an error while trying to map the results from Firebase

As a newcomer to the realm of React and Firebase, I find myself struggling with arrays and objects. It seems like the way my data is formatted or typed does not play well with the .map method. Despite scouring Stack Overflow for answers, none of the soluti ...

"Exploring the Power of Logarithmic Slider with Vue and Quasar

I'm currently working on a project utilizing Vue 2 and Quasar 1, where I am attempting to develop a logarithmic slider. Initially, I managed to create a basic example using a native input slider in this code pen: https://codepen.io/tonycarpenter/pen/Z ...

The Vue.js error message "Unable to access property 'array_name' as it is undefined" indicates an issue with

I'm currently working on fetching data using Axios requests and storing it in an array. Below is the code I have been using: props: [ 'products', ], data: function () { return { algolia: '', pro ...