Sorting arrays in JavaScript can become tricky when dealing with arrays that contain values from two different arrays

When working with two arrays in JavaScript that are received from PHP, I combine them into a single array. Each element in these arrays contains a created_at value (from Laravel), and I want to sort these elements by their created_at values.

The issue arises when the elements of the first array never get placed behind those of the second array, regardless of their dates. For example, if B has the latest date, C from the second array still appears after B.

The problem stems from the fact that even though I merge the two arrays, JavaScript treats them as separate entities, leading it to try sorting the first array's elements before the second array's.

To address this, my approach is:

history.push(...response.data[0]); // values from the first array
history.push(...response.data[1]); // values from the second array

history.sort((a, b) => {
            return a.created_at - b.created_at;
          });

As a result, the updated history should look like this:

[
// Elements from the first array
 {
  name: 'A',
  created_at: '08/09/2021'
 },
{
  name: 'B',
  created_at: '15/09/2021'
 },
// The third element is from the second array.
{
  name: 'C',
  created_at: '08/09/2021'
 }
]

The expected sorted history should be:

new sorted history:


 {
  name: 'A',
  created_at: '08/09/2021'
 },
{
  name: 'C',
  created_at: '08/09/2021'
 },
{
  name: 'B',
  created_at: '15/09/2021'
 }

However, due to JavaScript initially sorting the elements of the first array followed by the second array, the actual output appears as:


 {
  name: 'A',
  created_at: '08/09/2021'
 },
{
  name: 'B',
  created_at: '15/09/2021'
 },
{
  name: 'C',
  created_at: '08/09/2021'
 }

Answer №1

If you want to combine arrays in JavaScript, one approach is to use the array#concat method and implement the Schwartzian transform for sorting based on the created_at property. This involves converting the dates to a standardized format like YYYY-MM-DD for easier lexicographical sorting.

const arr1 = [{name: 'X', created_at: '08/09/2021'}],
      arr2 = [{name: 'Y', created_at: '15/09/2021'}, {name: 'Z', created_at: '08/09/2021'}],
      result = arr1.concat(arr2)
                   .map(obj => [obj.created_at.replace(/(..)\/(..)\/(....)/, '$3-$2-$1'), obj])
                   .sort((x,y) => x[0].localeCompare(y[0]))
                   .map(([,obj]) => obj);
console.log(result)

Answer №2

Make sure to provide a customized sorting function when using Array.sort()

const array = 
[
    { name: 'X', created_at: '08/10/2022' },
    { name: 'Y', created_at: '15/10/2022' },
    { name: 'Z', created_at: '08/10/2022' }
];

const dmyToYmd = (dmy) => { let splitDate = dmy.split('/'); return splitDate[2] + '/' + splitDate[1] + '/' + splitDate[0] }

const sortedArray = array.sort((element1, element2) => dmyToYmd(element1.created_at) > dmyToYmd(element2.created_at) ? 1 : -1);
console.log(sortedArray);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Update:

If you require a stable sort or need to prioritize date over alphabetically for your objects, then a more intricate sort function is necessary.

By incorporating Felix Kling's suggestion of localeCompare(), I enhanced the sorting method to ensure stability and prioritize dates followed by names.

const array =
    [
        { name: 'X', created_at: '08/10/2022' },
        { name: 'Z', created_at: '15/10/2022' },
        { name: 'Y', created_at: '15/10/2022' },
        { name: 'A', created_at: '15/10/2022' },
        { name: 'K', created_at: '08/10/2022', stable: '1'},
        { name: 'P', created_at: '08/10/2021' },
        { name: 'K', created_at: '08/10/2022', stable: '2' },
        { name: 'K', created_at: '08/07/2022' }
    ];

const dmyToYmd = (dmy) => { let splitDate = dmy.split('/'); return splitDate[2] + '/' + splitDate[1] + '/' + splitDate[0] }

const sortedArray = array.sort((element1, element2) =>
    (dmyToYmd(element1.created_at) === dmyToYmd(element2.created_at)) ?
        element1.name.localeCompare(element2.name) :
        dmyToYmd(element1.created_at).localeCompare(dmyToYmd(element2.created_at)));

console.log(sortedArray);

Resulting Output:

[
  { name: 'P', created_at: '08/10/2021' },
  { name: 'K', created_at: '08/07/2022' },
  { name: 'X', created_at: '08/10/2022' },
  { name: 'K', created_at: '08/10/2022', stable: '1' },
  { name: 'K', created_at: '08/10/2022', stable: '2' },
  { name: 'A', created_at: '15/10/2022' },
  { name: 'Y', created_at: '15/10/2022' },
  { name: 'Z', created_at: '15/10/2022' }
]

Answer №3

If you need to organize data by date values, one effective method is to utilize Date.prototype.getTime():

const items1 = [{category: 'X', date_added: '08/09/2021'}]
const items2 = [{category: 'Y', date_added: '15/09/2021'}, {category: 'Z', date_added: '08/09/2021'}]

const convertToDate= d => +d.replace(/\//g, '')
const sortedItems =  [...items1, ...items2].sort((a, b) => convertToDate(a.date_added) - convertToDate(b.date_added))

console.log(sortedItems)

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

Javascript/Jquery - Eliminating line breaks when transferring text to a textarea by copying and pasting

Is there a method to paste text into a textarea that will automatically remove any line breaks or whitespaces? For instance, if I copy the following text and paste it into the textarea: abcdef, ghijkl, mnopqrs I would like it to appear in the textarea as ...

Tips for adjusting the dimensions of my chart using JavaScript or Jquery

Utilizing DevExtreme widgets for the creation of a line chart in jQuery as shown below: var dataSource = [{"Date Range": "August-2018", Benelux: 194, Czech_Slovakia: 128, ...

utilize the flex index.html layout

Upon reviewing the template, I noticed that there is code implemented to check if the client has the necessary version. This code performs certain actions based on whether or not the required version is available. Additionally, there seems to be an <obj ...

Else statement malfunctioning with Alert() function

I have noticed an issue with my user input field. Even when I enter a valid genre name, the alert prompt still appears saying it is not a valid genre. This occurs after entering both valid and invalid inputs. For example, if the user enters "horror," whic ...

Using checkboxes in an Express application

Currently, I am working on the task of parsing checkbox values into an array using express/ejs. Users are required to fill out a form and select checkboxes as shown below: Answer: Checkbox: The goal is to create two arrays from the input data: answer = ...

Adjusting the size and location of the current browser window using jQuery

Is there a way to modify the height, width, and position of the browser window using jQuery's document.ready() function? ...

What could be causing my Ajax function to malfunction?

I've been attempting to incorporate a form that sends two javascript variables to a php script and displays the result in a new Div on the same page using an ajax function. Unfortunately, it's not functioning as expected. Here is the code snippe ...

Having trouble navigating through filtering in JavaScript using Node and Express?

After experimenting with different methods, I noticed that when using (age => age.Book === book && age.Chapter === 1) as my filter criteria, everything works perfectly. However, when I try using (age => age.Book === book && age.Chapt ...

Onload, capture page elements, delete them, and then access the original content

I am encountering two DIV elements on my page that I need to capture upon loading the page and preserve their contents until the page is refreshed. The nested DIV element is contained within the other one. After locating these elements initially, I want t ...

Using Regular Expressions for Validation

As a designer trying to set up a payment page without strong developer skills, I've hit some roadblocks. The payment company gave me guidance that involved using regular expressions for validating the 'AMOUNT' field, but my attempts to modif ...

What is the process for uploading or hosting a Reactjs website?

Currently, I am in the process of developing a React web application project using create-react-app. The project is nearly complete and as part of my preparation, I have been researching how to obtain a hostname. During my research, I came across https://w ...

Encountering a call stack size error when utilizing Vue-Resource within a Vuex store

I'm struggling to integrate an array from my api into a component using Vuex. The code I had when accessing the api directly from the component worked fine: data () { return { catalog:[], } }, created() { this.$http.get('https://example.net ...

How to Use Django to Load a Text File into an HTML File with the Help of

I came across an interesting code example on a website called w3schools.com that I would like to incorporate into my Django project. The code utilizes the jquery load() function to load a text file into an HTML file. Here is a snippet of the code: <!DOC ...

Creating dynamic elements in JavaScript and assigning them unique IDs

Hi there, I'm currently working on a project that requires generating dynamic divs with a textbox and delete button inside each one. The challenge I'm facing is figuring out how to assign a unique ID to each textbox element so that I can properly ...

Using AJAX in PHP to submit checkbox values in a form without reloading the page

Recently, I delved into learning ajax and found it to be truly amazing and a major time-saver. However, I encountered a roadblock when attempting to send form data without having the page reload. Here is an excerpt of my HTML code. <form id="form ...

Is there a way to remove CSS based on the generated HTML code?

Currently tackling a project in Next.js involving custom SCSS, Bootstrap SCSS, and React-Bootstrap. Struggling with the bloated size of our main.scss file due to unused CSS. After observing that 95% of the CSS is not utilized, I aim to eliminate all unnec ...

Creating dynamic routes in express.js with fixed components

I'm exploring how to create a route in express that captures URLs like this: /events/0.json Here's what I've attempted so far (but it's not working as expected): router.put('/events.json/:id.json', isLogged, events.update) ...

Encountering ReferenceError when attempting to declare a variable in TypeScript from an external file because it is not defined

Below is the typescript file in question: module someModule { declare var servicePort: string; export class someClass{ constructor(){ servicePort = servicePort || ""; //ERROR= 'ReferenceError: servicePort is not defined' } I also attempted t ...

Creating a dynamic method to set data for a stacked bar chart in chart.js

In the following code snippet, you can see how my stacked bar chart is rendered using Angular: <canvas baseChart [datasets]="barChartData" [labels]="barChartLabels" [options]="barChartOptions" [legend]="barChartLegend" [chartType]=" ...

Why is JavaScript globally modifying the JSON object?

I have a few functions here that utilize the official jQuery Template plugin to insert some JSON data given by our backend developers into the variables topPages and latestPages. However, when I use the insertOrHideList() function followed by the renderLis ...