1
votes

Tri du tableau d'objets avec plusieurs valeurs

Bonjour, j'ai ce tableau:

            array.sort(function(a,b){
                return new Date(b.datecrea) - new Date(a.datecrea);
            })
            .sort(function(a,b){
                return b.datas.downloads - a.datas.downloads;
            })

Je veux trier ce tableau mais en utilisant plusieurs valeurs et voici les étapes de tri:

  1. badge
    1. "bientôt" est le plus important
    2. "nouveau"
    3. "topten" est le moins important
  2. téléchargements
  3. datecrea

J'ai déjà ce code qui trie par date puis par téléchargement:

var array = [{
   "datecrea":"2020-01-31T16:14:46+01:00",
   "datas":{
      "badge":"new",
      "downloads":1,
   },
},
{
   "datecrea":"2020-01-31T17:14:46+01:00",
   "datas":{
      "badge":"soon",
      "downloads":0,
   },
},
{
   "datecrea":"2020-01-31T18:14:46+01:00",
   "datas":{
      "badge":"",
      "downloads":3,
   },
},
{
   "datecrea":"2020-01-31T19:14:46+01:00",
   "datas":{
      "badge":"topten",
      "downloads":5,
   },
},
{
   "datecrea":"2020-01-31T20:14:46+01:00",
   "datas":{
      "badge":"new",
      "downloads":1,
   },
}]


0 commentaires

4 Réponses :


0
votes

Je veux dire, ce n'est pas une méthode très propre pour faire le tri à plusieurs niveaux mais ...

...
.sort(function(a, b) {
   return rankBadge(a) - rankBadge(b);
})

function rankBadge(badge) {
    switch (badge) {
        case "soon": return 3;
        case "new": return 2;
        case "toptem": return 1;
        default: return 0;
    }
}


0 commentaires

2
votes

Vous pouvez créer un tableau des chaînes de badges, en fonction de leur "importance", puis avoir une fonction .sort qui trie par:

  • la différence entre les datecrea s. Si zéro, alors par
  • la différence dans les téléchargements . Si zéro, alors par
  • La différence d'index du badge dans le tableau de chaînes du badge
const badges = ['soon', 'new', 'topten', ''];
var array = [{
   "datecrea":"2020-01-31T16:14:46+01:00",
   "datas":{
      "badge":"new",
      "downloads":1,
   },
},
{
   "datecrea":"2020-01-31T17:14:46+01:00",
   "datas":{
      "badge":"soon",
      "downloads":0,
   },
},
{
   "datecrea":"2020-01-31T18:14:46+01:00",
   "datas":{
      "badge":"",
      "downloads":3,
   },
},
{
   "datecrea":"2020-01-31T19:14:46+01:00",
   "datas":{
      "badge":"topten",
      "downloads":5,
   },
},
{
   "datecrea":"2020-01-31T20:14:46+01:00",
   "datas":{
      "badge":"new",
      "downloads":1,
   },
},
{
   "datecrea":"2020-01-31T20:14:46+01:00",
   "datas":{
      "badge":"",
      "downloads":1,
   },
}]

array.sort((a, b) => (
  (badges.indexOf(a.datas.badge) - badges.indexOf(b.datas.badge)) ||
  (b.datas.downloads - a.datas.downloads) ||
  (new Date(b.datecrea) - new Date(a.datecrea))
));
console.log(array);

const badges = ['soon', 'new', 'topten', ''];
array.sort((a, b) => (
  (badges.indexOf(a.datas.badge) - badges.indexOf(b.datas.badge)) ||
  (new Date(b.datecrea) - new Date(a.datecrea)) ||
  (b.datas.downloads - a.datas.downloads)
));

N'appelez pas .sort deux fois - appelez-le seulement une fois et mettez toute la logique dans ce rappel. Si vous .sort deux fois, les résultats triés du premier .sort seront perdus, car le tableau sera complètement re-trié par le deuxième .sort .


2 commentaires

Merci beaucoup @CertainPerformance pour votre réponse, mais j'ai changé ma question, j'ai donné les étapes wong, en fait le tri doit se faire d'abord par le badge, par exemple, si un objet a un badge "bientôt" ce sera au sommet, peu importe ses téléchargements ou sa 'datecrea', merci beaucoup pour votre aide


Ensuite, inversez simplement le processus dans le .sort



2
votes

Vous n'avez pas besoin d'écrire trois méthodes sort () . Vous pouvez le faire en un seul sort () .

Quelque chose comme ceci:

var array = [{
    "datecrea": "2020-01-31T16:14:46+01:00",
    "datas": {
      "badge": "new",
      "downloads": 1,
    },
  },
  {
    "datecrea": "2020-01-31T17:14:46+01:00",
    "datas": {
      "badge": "soon",
      "downloads": 0,
    },
  },
  {
    "datecrea": "2020-01-31T18:14:46+01:00",
    "datas": {
      "badge": "",
      "downloads": 3,
    },
  },
  {
    "datecrea": "2020-01-31T19:14:46+01:00",
    "datas": {
      "badge": "topten",
      "downloads": 5,
    },
  },
  {
    "datecrea": "2020-01-31T20:14:46+01:00",
    "datas": {
      "badge": "new",
      "downloads": 1,
    },
  }
]

const badgeWeights = {
  soon: 3,
  new: 2,
  topten: 1,
};

const result = array.sort(function(a, b) {
  if (a.datecrea !== b.datecrea) {
    return new Date(b.datecrea) - new Date(a.datecrea);
  }
  
  if (a.datas.downloads !== b.datas.downloads) {
    return b.datas.downloads - a.datas.downloads;
  }
  
  const aWeight = a.datas.badge ? badgeWeights[a.datas.badge] : 0;
  const bWeight = b.datas.badge ? badgeWeights[b.datas.badge] : 0;
  
  return bWeight - aWeight;
});

console.log(result);


0 commentaires

0
votes

Vous pouvez utiliser Array.sort () avec plusieurs comparaisons. Et vous pouvez créer un objet contenant les classements des badges à utiliser pour le tri.

var items=[{datecrea:"2020-01-31T16:14:46+01:00",datas:{badge:"new",downloads:1}},{datecrea:"2020-02-12T17:14:46+01:00",datas:{badge:"soon",downloads:0}},{datecrea:"2020-01-28T18:14:46+01:00",datas:{badge:"",downloads:3}},{datecrea:"2020-03-31T19:14:46+01:00",datas:{badge:"topten",downloads:5}},{datecrea:"2020-01-31T20:14:46+01:00",datas:{badge:"new",downloads:3}}];

let badgeRanks = {
  soon: 3,
  new: 2,
  topten: 1

}

items.sort(function(item1, item2) {

  let date1 = new Date(item1.datecrea)
  let date2 = new Date(item2.datecrea)

  if (date1.getTime() > date2.getTime()) return -1;
  if (date1.getTime() < date2.getTime()) return 1;

  if (item1.datas.downloads > item2.datas.downloads) return -1;
  if (item1.datas.downloads < item2.datas.downloads) return 1;

  if (badgeRanks[item1.datas.badge] > badgeRanks[item2.datas.badge]) return -1;
  if (badgeRanks[item1.datas.badge] < badgeRanks[item2.datas.badge]) return 1;


});

console.log(items);


0 commentaires