How to organize a JSON by date

Asked

Viewed 120 times

-6

I have this JSON and I must arrange it by data:

{
    "clients": [
        { "id": 1, "name": "Juca" },
        { "id": 2, "name": "Beto" }
    ],
    "purchase": [
        { "client_id": 1, "data": "11/04/2021", "total": 100.0 },
        { "client_id": 2, "data": "11/03/2021", "total": 83.71 },
        { "client_id": 2, "data": "08/02/2021", "total": 52.48 },
        { "client_id": 1, "data": "20/04/2021", "total": 399.99 }
    ]
}

In case I have a file (main.js) that imports the file object . json and prints for each customer their data, their ordered purchases by date and the total in purchases.

This is the expected response:


Client 1 - Juca

Purchase on 04/11/2021 in total R$ 100.00

Purchase in 04/20/2021 in total R$ 399.99

Customer total: R$ 499.99

Client 2 - Beto

Purchase on 02/08/2021 in total R$ 52.48

Purchase on 03/11/2021 in total R$ 83.71

Customer total: R$ 136.19


I’ve tried to use sort() string manipulation using the split('/') but nothing returns me the expected answer.

Obs.: code execution must be done using Node --experimental-json-modeules main.js

  • 3

    Your question is a little ambiguous, I suggest [Edit] to put the expected result. The JSON format should remain the same, just by ordering the purchase for client_id and subsequently data?

  • I agree with @Rafaeltavares regarding this. I answered your question based on what I was able to extract (perhaps with a solution where you can try to apply in your project)

2 answers

-2


Updated

If it is to arrange by customer code and dates in ascending order (both things), then you can use a .sort() with a return within a if comparing dates if the client code is equal in the two arguments of the .sort(), or by returning the client code in the smaller order to larger as code below:

var data = {
    "clients": [
        { "id": 1, "name": "Juca" },
        { "id": 2, "name": "Beto" }
    ],
    "purchase": [
        { "client_id": 1, "data": "11/04/2021", "total": 100.0 },
        { "client_id": 2, "data": "11/03/1998", "total": 83.71 },
        { "client_id": 2, "data": "08/02/2021", "total": 52.48 },
        { "client_id": 1, "data": "20/04/2021", "total": 399.99 },
        { "client_id": 3, "data": "20/04/2021", "total": 1.99 },
        { "client_id": 4, "data": "20/04/2019", "total": 2.99 },
        { "client_id": 1, "data": "29/12/2021", "total": 4.99 },
        { "client_id": 2, "data": "01/01/1990", "total": 5.99 },
        { "client_id": 3, "data": "19/04/2021", "total": 7.99 },
        { "client_id": 4, "data": "21/01/1990", "total": 7.99 }
    ]
}

function dataFormat(d){
   
   var d_split = d.split("/");
   var dia = d_split[0];
   var mes = d_split[1]-1; // diminui por 1 porque os meses começam com 0
   var ano = d_split[2];

   return [dia,mes,ano];
}


data.purchase.sort(function(a,b){
   if(a.client_id == b.client_id){
      return new Date(dataFormat(a.data)[2], dataFormat(a.data)[1], dataFormat(a.data)[0]) - new Date(dataFormat(b.data)[2], dataFormat(b.data)[1], dataFormat(b.data)[0]);
   }
   return a.client_id - b.client_id;
});
 

console.log(data.purchase);

Note that on the dates, on the object new Date(), I used the pattern ano, mês, dia to compare whether one date is smaller (older) than the other.

The result of the above code is:

0: {client_id: 1, data: "11/04/2021", total: 100}
1: {client_id: 1, data: "20/04/2021", total: 399.99}
2: {client_id: 1, data: "29/12/2021", total: 4.99}
3: {client_id: 2, data: "01/01/1990", total: 5.99}
4: {client_id: 2, data: "11/03/1998", total: 83.71}
5: {client_id: 2, data: "08/02/2021", total: 52.48}
6: {client_id: 3, data: "19/04/2021", total: 7.99}
7: {client_id: 3, data: "20/04/2021", total: 1.99}
8: {client_id: 4, data: "21/01/1990", total: 7.99}
9: {client_id: 4, data: "20/04/2019", total: 2.99}

-3

Based on your question I have found the following solution..

In short, I have stored the dates in a new Array and turned them into timestamp, into research, a single instant according to hkotsubo’s blog. Because it is a specific point in the timeline, in other words, it undergoes increasing changes over time, so we can deal with these dates without having to turn them into figures, which would bring a series of conflicts..

// para fins de obter as datas, basta você percorrer todo o json e obter as respectivas datas conforme deseja..
var datasArr = ["11/04/2021", "11/03/2021", "08/02/2021", "20/04/2021"];

// transforma o datetime para timestamp
const timestamp = input => Math.floor(Date.parse(input) / 1000);

// mapeio todo o array contendo as datas e os formato em "yyyy mm dd"
datasArr = datasArr.map(data => {
   var [dia, mes, ano] = data.split("/").map(d => d.padStart(d.length, "0"));
   return timestamp(`${ano} ${mes} ${dia}`);
});

// imprime as datas formatadas para timestamp..
console.log(datasArr);

Great formatted dates! as mentioned in the question, I used the function itself sort() of to sort these values from smaller to larger

var datasArr = ["11/04/2021", "11/03/2021", "08/02/2021", "20/04/2021"];

const timestamp = input => Math.floor(Date.parse(input) / 1000);

datasArr = datasArr.map(data => {
   var [dia, mes, ano] = data.split("/").map(d => d.padStart(d.length, "0"));
   return timestamp(`${ano} ${mes} ${dia}`);
});

// aqui ele vai ordenar as datas no formato de timestamp, assim na hora de converter 
// as datas estarão ordenadas do menor para maior e no formato dd/mm/yyyy
datasArr = datasArr.sort((a, b) => {
   return a - b
});

var convertDatasArr = datasArr.map((timestamp) => {
   return new Date(timestamp * 1000).toLocaleDateString("pt-BR");
});

// imprime as datas no formato dd/mm/yyyy de forma ordenada
console.log(convertDatasArr);


Obs.: it is worth noting that the above code corresponds to "how to arrange dates from oldest to newest." So I’m waiting for the author to use the criteria of How to create a Minimum, Complete and Verifiable example to include more details in the question, so that you can actually examine it completely!

  • 1

    Turning into numbers is not a good one because there are cases that can have zero left. For example, if you have "12/08/2021" and "04/20/2021" (December 8 and April 20), when turning into numbers they saw 8122021 and 20042021 (8 million and 20 million), and will say that April 20 is higher (December 8 is higher). The ideal is to turn everything into Date even, and not need to create functions for the largest and smallest, just use Math.max and Math.min. And of course you still have the job of converting back to the original format. Something like this: https://ideone.com/lFMd3y

  • 2

    Anyway, the question is still unclear and I don’t know if it really answers. From what I understand, he wants to sort the dates according to some criteria, and not just take the biggest and smallest. Let’s wait and see if the author clarifies...

  • Okay, then I correct the answer, I was a bit on the back foot too, I know he didn’t want to get smaller and higher value, but based on the question was the solution I found.. I await the author’s clarification!

  • 1

    @hkotsubo fixed problem! fixed so far this issue of having cases "zero on the left"

  • 1

    If you have separated the values of the day, month and year with split, could use them directly, as I did here. Turn them into another string to pass it to Date.parse is an unnecessary turn. Not to mention that it is not recommended to use non-standard formats, because it is not guaranteed to work the same in all browsers (understand better by reading here). And I also did not understand why divide the timestamp by 1000 only to then multiply by 1000 (in this case it makes no difference, but if you had the time, the floor would lose the fractions of a second)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.