1
votes

Quelle est la bonne façon d'utiliser array.sort (a, b) suite aux modifications apportées dans node.js v11.0.0 ^

Ok, donc nous avions du code qui fonctionnait bien et qui passait les tests correctement sur le nœud 10, maintenant après la mise à niveau vers le nœud 11, le code échoue désormais aux tests unitaires. Le code mappe sur un tableau d'objets modifiant les propriétés puis trie en fonction d'une valeur de nom de chaîne, c'est-à-dire array.sort (a, b) => a.toLowerCase ()> b.toLowerCase ().

Il correspond maintenant correctement mais le tri le fait ne fonctionne pas et retourne le tableau mappé uniquement sans trier, quand j'ai essayé de diviser les deux fonctions en une carte individuelle, puis trier le tri renvoie undefined.

J'ai recherché et essayé de trouver des exemples pour voir ce dont les besoins à changer mais pas trouvé beaucoup autre que des suggestions de l'algorithme de tri changeant en tri temporel dans la v8.

code simple

      {value: 'CA076757', label: 'Brockway'},
      {value: 'MN486464', label: 'Ogdenville'}.
      {value: 'S4889785', label: 'North Haverbrook'}
    ]

tableau de test:

      {value: 'CA076757', label: 'Brockway'},
      {value: 'S4889785', label: 'North Haverbrook'},
      {value: 'MN486464', label: 'Ogdenville'}
    ]

résultat attendu

      type: 'Place',
      properties: {
        code: 'CA076757',
        name: 'Brockway'
      }
    }, {
      type: 'Place',
      properties: {
        code: 'MN486464',
        name: 'Ogdenville'
      }
    }, {
      type: 'Place',
      properties: {
        code: 'S4889785',
        name: 'North Haverbrook'
      }
    }]

résultat réel

export default places => places
   .map(place => ({
    value: place.properties.code, label: place.properties.name
   }))
   .sort((placeA, placeB) => placeA.label.toLowerCase() > 
   placeB.label.toLowerCase())


2 commentaires

en utilisant > comme comparateur implique que les valeurs sont égales quand a , donc l'implémentation a la liberté de les échanger, ou non, car la spécification ne garantit pas un algorithme de tri stable.


Merci à tous pour votre aide et vos explications sur le comportement et les raisons pour lesquelles les choses se passent, tous incroyablement utiles :) beaucoup de mercis


4 Réponses :


0
votes

Vous pouvez utiliser localeCompare pour cela: XXX

Sortie:

[ { value: 'CA076757', label: 'Brockway' },
  { value: 'S4889785', label: 'North Haverbrook' },
  { value: 'MN486464', label: 'Ogdenville' } ]


1 commentaires

C'est un bon conseil, mais gardez à l'esprit que localeCompare a des avantages et des inconvénients: du côté pro, il prend en compte les paramètres régionaux actuels, ce qui peut être très souhaitable (ou, lors de l'exécution dans les navigateurs, peut conduire à un comportement différent pour différents utilisateurs, ce qui peut être étrange). Du côté des inconvénients, il a tendance à être plus lent que les alternatives plus primitives et non sensibles aux paramètres régionaux, ce qui peut ou non avoir une importance pour un cas d'utilisation donné.



4
votes

nous avions un code qui fonctionnait bien et qui passait les tests correctement sur le nœud 10, maintenant après la mise à niveau vers le nœud 11, le code échoue désormais aux tests unitaires

Pour être franc, cela signifie que vos tests ne fournissent pas une couverture suffisante ;-)

En JavaScript, une fonction de comparaison cmp (a, b) pour Array.sort doit renvoyer:

  • une valeur inférieure à zéro si a est inférieur à b
  • zéro si a est égal à b
  • une valeur supérieure à zéro si a est supérieur à b

Si vous utilisez une fonction de comparaison qui renvoie une valeur booléenne, alors false mappera silencieusement sur 0 , et true mappera silencieusement à 1 . Il n'y a aucun moyen de signaler le cas a . Si vos cas de test sont de toute façon triés (ou utilisés pour obtenir) correctement, ils ne couvrent pas ce cas.

Une fonction de comparaison appropriée pour votre exemple, quelle que soit la version de Node ou le navigateur que vous utilisez en utilisant, serait:

(placeA, placeB) => {
  let a = placeA.label.toLowerCase();
  let b = placeB.label.toLowerCase();
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
}

0 commentaires

0
votes

D'après ma réponse à Trier un tableau d'objets par valeur de propriété de chaîne , un moyen suffisant de trier les chaînes lorsque les paramètres régionaux de chaîne ne sont pas importants, c'est l'approche suivante:

const sortBy = fn => (a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) || +(fa > fb)
}

const sortByLabelCaseInsensitive = sortBy(
  place => place.label.toLowerCase()
)

const fn = places => places.map(place => ({
  value: place.properties.code,
  label: place.properties.name
})).sort(sortByLabelCaseInsensitive)

const array = [{
  type: 'Place',
  properties: {
    code: 'CA076757',
    name: 'Brockway'
  }
}, {
  type: 'Place',
  properties: {
    code: 'MN486464',
    name: 'Ogdenville'
  }
}, {
  type: 'Place',
  properties: {
    code: 'S4889785',
    name: 'North Haverbrook'
  }
}]

console.log(fn(array))


0 commentaires

0
votes

essayez celui-ci

.sort((placeA, placeB) => { 
   if(placeA.label.toLowerCase() < placeB.label.toLowerCase()) return -1
   if(placeA.label.toLowerCase() > placeB.label.toLowerCase()) return 1
   return 0;
});

Vous devez comparer chaque élément avec le suivant et renvoyer qu'il est égal, supérieur ou inférieur


0 commentaires