1
votes

Trier un tableau d'une certaine manière

J'ai un tableau qui est rempli d'options dans les listes déroulantes sélectionnées.

jQuery('.wcpf-input-drop-down').each(function () {
var sel = jQuery(this);
var selected = sel.val(); // cache selected value, before reordering
var opts_list = sel.find('option');
opts_list.sort(function(a, b) { return jQuery(a).text() > jQuery(b).text() ? 1 : -1; });
sel.html('').append(opts_list);
sel.val(selected); // set cached selected value
    });

Le code ci-dessus provient de Tri des éléments d'options par ordre alphabétique en utilisant jQuery , écrit par Malak George. EDIT: Je l'ai modifié pour rechercher toutes les instances séparément.

Maintenant, cela fonctionne très bien en ce qui concerne la recherche des instances de .wcpf-input-drop-down et le tri des options à l'intérieur. p>

Cependant, ce tri produit l'ordre de cette manière: "1, 2, 26, 27, 28, 3, 31" et ainsi de suite.

J'en aurais besoin pour trier comme suit: "1, 2, 3, 26, 27, 28, 31".

Je cherche depuis des heures et j'ai trouvé beaucoup de discussions sur le sujet, mais je n'arrive pas à aller où je veux. Je suis sûr que j'ai vu des moyens d'accomplir ce dont j'ai besoin, mais je n'ai pas pu le faire. Je pense en voici un que je pourrais utiliser, si je savais seulement comment l'insérer dans mon code existant: Trier les éléments du tableau (chaîne avec des nombres), tri naturel

Quelqu'un pourrait-il m'aider à implémenter le tri que je souhaite voir dans le code que j'ai maintenant? p>

Merci.

EDIT2: Voici un stylo avec toutes les données pertinentes pour cette question: https://codepen.io/jpontinen/pen/NJrXKQ


4 commentaires

Par quelle partie des options triez-vous? valeur ou texte?


Pouvez-vous aussi partager le HTML associé? Si possible, pouvez-vous partager un codepen / jsbin ou quelque chose de similaire. Pour autant que je sache, cela se produit parce que la méthode text () renverrait une chaîne, vous devrez la convertir en entier par la méthode parseInt (). Je peux examiner le code si vous pouvez le partager dans bin.


Merci pour vos réponses. Voici un stylo avec toutes les données pertinentes: codepen.io/jpontinen/pen/NJrXKQ


C'est parce qu'en utilisant jQuery (a) .text () vous obtenez une chaîne. la comparaison de chaînes (qui sont en réalité des nombres) est différente de la comparaison des nombres. par exemple, les chaînes de caractères «26»> «3» renverront false. 26> 3 retournera vrai


3 Réponses :


1
votes

Soustrayez les options de votre rappel de tri, de cette façon, elles sont automatiquement forcées au type de données numériques:

opts_list.sort(function(a, b) { 
  return jQuery(a).text().localeCompare(jQuery(b).text(), undefined, {numeric: true, sensitivity: 'base'});
});

Si vous avez également des listes déroulantes contenant des données non numériques, tri alphabétique, alors vous avez besoin d'une méthode de tri naturel:

opts_list.sort(function(a, b) { 
     return jQuery(a).text() - jQuery(b).text()
});


2 commentaires

Ah, désolé, j'ai oublié de mentionner - j'ai utilisé le tri alphabétique, car je ne sais pas exactement ce que mon client va entrer. Les options concernent, en pratique, les pneus / roues de véhicules et elles peuvent également contenir des lettres.


Veuillez envisager de donner à ma question un +1, je pense que je l'ai posée d'une manière approuvée par SO. Merci!



0
votes

Le problème est que vous triez les chaînes lexicographiquement ("26" vient avant "3").

Vous voulez trier par valeur numérique (en convertissant les chaînes en nombres):

// Explicitly convert to integer type using parseInt.
// Note `jQuery(a).text()` can be simplified to `a.text`
opts_list.sort(function(a, b) {
    return parseInt(a.text, 10) - parseInt(b.text, 10);
});


2 commentaires

Merci. Je suis sûr que ces options profiteront à beaucoup. Les réponses que j'ai trouvées sur SO avant ma question étaient incroyablement étirées, 10 à 40 lignes de code avec des liens vers des plugins externes et toutes sortes de manigances. Veuillez envisager de donner à ma question un +1, je pense que je l'ai posée d'une manière approuvée par SO.


La dernière option n'est pas correcte. Il doit utiliser textContent



0
votes

Les détails sont commentés dans la démo.

<select class="sel">
  <option value="0">0</option>
  <option value="1">1</option>
  <option value="10">10</option>
  <option value="107">107</option>
  <option value="108">108</option>
  <option value="11">11</option>
  <option value="75">75</option>
  <option value="8">8</option>
  <option value="83">83</option>
  <option value="9">9</option>
  <option value="110">110</option>
  <option value="111">111</option>
  <option value="114">114</option>
  <option value="12">12</option>
  <option value="71">71</option>
  <option selected>Values to be sorted</option>
</select>

<hr>

<select class="sel">
  <option value="11">11</option>
  <option value="89">89</option>
  <option value="5">5</option>
  <option value="0">0</option>
  <option value="46">46</option>
  <option value="33">33</option>
  <option value="1">1</option>
  <option value="6">6</option>
  <option value="21">21</option>
  <option value="40">40</option>
  <option value="24">24</option>
  <option value="175">175</option>
  <option value="81">81</option>
  <option value="123">123</option>
  <option value="94">94</option>
  <option selected>Values to be sorted</option>
</select>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
/* 
On each select.sel...
...get all of its options...
...then make an array of those option.
Next, sort the array of options by their .value...
...and remove everything in select.sel...
...and append the sorted array in select.sel
*/
$('.sel').each(function(i) {
  var opt = $(this).find('option');
  var arr = $.makeArray(opt);
  var sorted = arr.sort(function(a, b) {
    return parseInt(a.value, 10) - parseInt(b.value, 10);
  });
  $(this).empty().append(sorted);
});


0 commentaires