Cela semblera être un problème facile, mais j'ai passé mon dimanche à essayer de comprendre ce qui ne va pas avec mon implémentation décrite ci-dessous, donc je le poste sur SO en dernier recours.
J'ai une application javascript qui reçoit des structures de données d'un serveur. Le côté serveur envoie les données non triées pour des raisons de performances.
Voici un extrait du code javascript recevant les données:
var seriesRawDataArray = ko.observableArray();
...
analyticscontext.series(seriesRawDataArray).done(function () {
renderSeries();
});
Le module analyticscontext
interroge les données en utilisant ajax:
function series(seriesData) {
return $.ajax({
url: "/api/analytics/series",
type: "GET",
success: function (data) {
return seriesData(data);
}
});
}
renderSeries
effectue un tri sur les données avant de les rendre:
// Sort the data by date using moment.js
seriesRawDataArray.sort(function (left, right) {
var leftDate = moment.utc(left.timeStamp);
var rightDate = moment.utc(right.timeStamp);
var diff = leftDate.diff(rightDate);
return diff > 0;
});
Problème [~ # ~] [~ # ~]
Voici un échantillon de données que je reçois de mon serveur:
Remarquez les articles non triés à la fin. le seriesRawDataArray.sort
semble n'avoir aucun effet sur le tableau d'origine qui n'est pas trié quoi que je change dans la méthode de tri. La sortie est toujours:
Notez les éléments non triés ici. Les bibliothèques que j'utilise et les données ne sont certainement pas le problème car cela jsfiddle fonctionne très bien! Y a-t-il un problème avec ce code?
Vous devez renvoyer la différence entre les deux dates, pas un booléen:
// sort the data by date using moment.js
seriesRawDataArray.sort(function (left, right) {
return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))
});
Array.prototype.sort
s'attend à ce qu'une valeur négative, nulle ou positive soit renvoyée. Généralement, vous écrirez une fonction de tri comme celle-ci:
yourArray.sort(function (a, b) {
if (a < b) { // a comes first
return -1
} else if (b < a) { // b comes first
return 1
} else { // equal, so order is irrelevant
return 0 // note: sort is not necessarily stable in JS
}
})
La fonction anonyme passée à sort sert de comparateur pour l'implémentation native de la fonction sort.
Cependant, votre valeur négative ne doit pas nécessairement être -1
Et votre valeur positive ne doit pas être +1
. Par conséquent, lors du tri des nombres, vous pouvez utiliser à la place le raccourci:
yourArray.sort(function (a, b) {
return a - b
})
En JavaScript, la soustraction de deux dates les contraint à la fois en nombres, c'est pourquoi nous pourrions utiliser return moment.utc(left.timeStamp).diff(moment.utc(right.timeStamp))
(au lieu de la soustraction directe -
, cette méthode utilise moment.prototype.diff
de la bibliothèque moment.js
)
Cependant , dans votre code, vous avez renvoyé diff > 0
, Qui peut être true
ou false
. En raison de la contrainte de type, JavScript lira true
comme 1
Et false
comme 0
. Cela signifie que votre fonction de tri ne renverra jamais -1
. Par conséquent, vos éléments ne seront pas triés correctement.
let _sortedDates = dates.sort(function(a, b){
return moment(b).format('X')-moment(a).format('X')
});
Étant donné que moment peut formater des dates valides, la meilleure façon est d'utiliser la méthode de tri javascript, donc lors du formatage de la date en horodatage, vous triez essentiellement par numéro.
Références: momentjs.com/docs/#/displaying/format, w3schools.com/jsref/jsref_sort.asp