JQuery / Javascript - Sort Multidimensional Array ()

1

I have the following Array ():

{
    "1 ":
        {
            "id":"12",
            "usuarioA":"1",
            "usuarioB":"2",
            "mensaje":"Hola mi amor",
            "date":"2017-01-19 03:02:12",
            "TokenID":"1",
            "remitente":"Andrey Homez",
            "destinatario":"Paola Gonzales",
            "CVX":"Paola Gonzales"
        },
    "2 ":
        {
            "id":"13",
            "usuarioA":"1",
            "usuarioB":"3",
            "mensaje":"hey chaval",
            "date":"2017-01-19 03:11:11",
            "TokenID":"2",
            "remitente":"Andrey Homez",
            "destinatario":"Felipe Gomez",
            "CVX":"Felipe Gomez"
        },
    "13 ":
        {
            "id":"11",
            "usuarioA":"1",
            "usuarioB":"1",
            "mensaje":"Hablando conmigo mismo alv :"v",
            "date":"2017-01-19 02:52:13",
            "TokenID":"13",
            "remitente":"Andrey Homez",
            "destinatario":"Andrey Homez",
            "CVX":"Andrey Homez"
        }
}

How can I make sorted by the "date" index in descending ? In other words, it looks like this:

{
    "2 ":
        {
            "id":"13",
            "usuarioA":"1",
            "usuarioB":"3",
            "mensaje":"hey chaval",
            "date":"2017-01-19 03:11:11",
            "TokenID":"2",
            "remitente":"Andrey Homez",
            "destinatario":"Felipe Gomez",
            "CVX":"Felipe Gomez"
        },
    "1 ":
        {
            "id":"12",
            "usuarioA":"1",
            "usuarioB":"2",
            "mensaje":"Hola mi amor",
            "date":"2017-01-19 03:02:12",
            "TokenID":"1",
            "remitente":"Andrey Homez",
            "destinatario":"Paola Gonzales",
            "CVX":"Paola Gonzales"
        },

    "13 ":
        {
            "id":"11",
            "usuarioA":"1",
            "usuarioB":"1",
            "mensaje":"Hablando conmigo mismo alv :"v",
            "date":"2017-01-19 02:52:13",
            "TokenID":"13",
            "remitente":"Andrey Homez",
            "destinatario":"Andrey Homez",
            "CVX":"Andrey Homez"
        }
}

Something important is that the numbers 1 , 2 , 13 should be retained (I do not mean your order).

Thanks, in advance:)

    
asked by Máxima Alekz 19.01.2017 в 09:22
source

2 answers

4

The problem, to begin with, is that your data does not correspond to a matrix, but to an object. JavaScript does not understand associative matrices, instead uses objects and properties to achieve similar functionality.

This means that methods such as sort() are not available for data ordering and, what's worse, JavaScript does not guarantee the order of the properties throughout the life of the object , so the result should be in any case a matrix, not a new object.

To correct this problem, I recommend that you generate your data as a matrix (using root delimiters [] instead of {} ). You will not have any loss because the index of the values is, in fact, the field tokenID .

Once that modification is made, it is very easy to use a comparison function to sort your data as you wish.

If you can not make that change in your code, then you can do an object conversion > matrix as you proposed @PaperBirdMaster, but always it is better to do this work in origin than in the client's browser .

This is the example of doing everything as an object (you will see that the result is "reordered"):

var datos = {
  "1":{
    "id":"12",
    "usuarioA":"1",
    "usuarioB":"2",
    "mensaje":"Hola mi amor",
    "date":"2017-01-19 03:02:12",
    "TokenID":"1",
    "remitente":"Andrey Homez",
    "destinatario":"Paola Gonzales",
    "CVX":"Paola Gonzales"
  },
  "2":{
    "id":"13",
    "usuarioA":"1",
    "usuarioB":"3",
    "mensaje":"hey chaval",
    "date":"2017-01-19 03:11:11",
    "TokenID":"2",
    "remitente":"Andrey Homez",
    "destinatario":"Felipe Gomez",
    "CVX":"Felipe Gomez"
  },
  "13":{
    "id":"11",
    "usuarioA":"1",
    "usuarioB":"1",
    "mensaje":"Hablando conmigo mismo alv :"v",
    "date":"2017-01-19 02:52:13",
    "TokenID":"13",
    "remitente":"Andrey Homez",
    "destinatario":"Andrey Homez",
    "CVX":"Andrey Homez"
  }
};
var temp = [];
for (var i in datos) {
  array.push(datos[i]);
}
function sort(a,b){
  a = a.date;
  b = b.date;
  if(a < b) {
    return 1;
  } else if (a > b) {
    return -1;
  }
  return 0;
}
temp.sort(sort);
salida = {};
for (var i in temp) {
  salida[temp[i].TokenID] = temp[i];
}
console.log(salida);

And this one as a matrix (declaring the data as a starting matrix, to avoid the conversion loop):

var datos = [
  {
    "id":"12",
    "usuarioA":"1",
    "usuarioB":"2",
    "mensaje":"Hola mi amor",
    "date":"2017-01-19 03:02:12",
    "TokenID":"1",
    "remitente":"Andrey Homez",
    "destinatario":"Paola Gonzales",
    "CVX":"Paola Gonzales"
  },
  {
    "id":"13",
    "usuarioA":"1",
    "usuarioB":"3",
    "mensaje":"hey chaval",
    "date":"2017-01-19 03:11:11",
    "TokenID":"2",
    "remitente":"Andrey Homez",
    "destinatario":"Felipe Gomez",
    "CVX":"Felipe Gomez"
  },
  {
    "id":"11",
    "usuarioA":"1",
    "usuarioB":"1",
    "mensaje":"Hablando conmigo mismo alv :&quot;v",
    "date":"2017-01-19 02:52:13",
    "TokenID":"13",
    "remitente":"Andrey Homez",
    "destinatario":"Andrey Homez",
    "CVX":"Andrey Homez"
  }
];
function sort(a,b){
  a = a.date;
  b = b.date;
  if(a < b) {
    return 1;
  } else if (a > b) {
    return -1;
  }
  return 0;
}
datos.sort(sort);
console.log(datos);

In this case the comparison between dates is simple because they seem to be obtained from a database in yyyy-mm-dd HH:MM:SS format that allows equivalence with the direct comparison of character strings.

You must make sure that these dates are in UTC to avoid problems with the comparisons during the periods of a change of time (summer time to winter time and vice versa).

    
answered by 19.01.2017 / 12:18
source
5

Problem.

  

I have the following Array ():

No, that's not an Array: it's an object. Objects do not order their elements.

According to the object definition of the 3rd edition of ECMAScript (translated and highlighted by me):

  

4.3.3 Object

     

An object is a member of type Object . It is an unordered collection of properties each of which contains a primitive value, object or function. A function stored in a property of an object is known as a method.

Proposal.

Pass the elements to an array, you can do it like this:

var x = { ... todos tus datos ... };
var array = [];
for (var id in x)
{
    var obj = {};
    obj[id] = x[id];
    array.push(obj);
}

JavaScript arrays have a sort function which can (optionally) receive a parameter that is the comparison function. So we will create a function that orders us inversely according to the property "date" of the object:

function date_descendente(a, b) {
    var split_a = a[Object.keys(a)[0]]["date"].match(/(\d+)/g);
    var split_b = b[Object.keys(b)[0]]["date"].match(/(\d+)/g);
    var date_a = new Date(split_a[0], split_a[1], split_a[2], split_a[3], split_a[4], split_a[5]);
    var date_b = new Date(split_b[0], split_b[1], split_b[2], split_b[3], split_b[4], split_b[5]);

    return date_b.getTime() - date_a.getTime();
}

As far as I can see, the Date object is not buildable with the date format that stored (if it did not include the seconds it would be constructible). So I separate the date in each of the components and build the date from them with the constructor that receives year, month, day, hour, minute and second.

To order the inverse I simply return the subtraction between the element on the right and the one on the left, since the sort function needs to return a numerical value we subtract the result of calling the method getTime of each Date , which returns the milliseconds elapsed since January 1, 1970 at 0 o'clock (which is what is known as UNIX Time ).

So the code would look like this:

var array = [];
for (var id in x)
{
    var obj = {};
    obj[id] = x[id];
    array.push(obj);
}
array.sort(date_descendente);

And you would have in array[0] the object "2" , 1 "12" and 2 "13" .

    
answered by 19.01.2017 в 11:38