web-dev-qa-db-fra.com

Trier un tableau sauf un élément en JavaScript

J'ai un tableau et je le trie mais je dois tout trier sauf un élément de mon tableau.

Mon tableau est:

var Comparison = [
    {key: "None", value: "None"},
    {key:"Geographical Area", value:"Geographical_Area"},
    {key:"Forests", value:"Forests"},
    {key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"},
    {key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"},
    {key:"Land Area", value:"Land_Area"},
    {key:"Water Area", value:"Water_Area"},
    {key:"Culturable Waste", value:"Culturable_Waste"},
    {key:"Permanent Pastures", value:"Permanent_Pastures"},
    {key:"Land under Tree Crops", value:"Land_under_Tree_Crops"},
    {key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"},
    {key:"Current Fallow", value:"Current_Fallow"},
    {key:"Total Unculturable Land", value:"Total_Unculturable_Land"},
    {key:"Net Sown Area", value:"Net_Sown_Area"},
    {key:"Gross Sown Area", value:"Gross_Sown_Area"},
    {key:"Cropping Intensity", value:"Cropping_Intensity"} ];

Je trie ce tableau en utilisant ce code:

var Comparison_sort = this.Comparison.sort(function (a, b) {
  if (a.key < b.key)
      return -1;
  if (a.key > b.key)
      return 1;
  return 0;
});

Cela trie parfaitement mon tableau, mais je veux que l'un de mes éléments soit en haut, ce qui signifie que mon élément Aucun ne devrait pas être en haut et trier tous les autres éléments.

Par exemple, j'obtiens ce résultat:

   {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
   {key: "Cropping Intensity", value: "Cropping_Intensity"}
   {key: "Culturable Waste", value: "Culturable_Waste"}
    ....
   {key: "None", value: "None"}

Mais je veux un résultat comme celui-ci:

   {key: "None", value: "None"}
   {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}
   {key: "Cropping Intensity", value: "Cropping_Intensity"}
   {key: "Culturable Waste", value: "Culturable_Waste"}
    ....

J'ai vu une réponse, Tableau de tri en TypeScript, mais je n'ai pas pu utiliser cette réponse à mon problème.

21
Nilay Singh
var Comparison_sort = this.Comparison.sort(function (a, b) {
  if(a.key == b.key) return 0;
  if (a.key == 'None') return -1;
  if (b.key == 'None') return 1;

  if (a.key < b.key)
      return -1;
  if (a.key > b.key)
      return 1;
  return 0;
});

indique "faire un tri régulier, sauf si la clé n'est pas ce qui signifie qu'elle doit aller en premier".

17
spi

Pas compliqué, mais une façon assez simple de le faire est de simplement supprimer l'élément spécial, de trier le tableau et d'insérer le spécial dans l'index de votre choix.

var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];

const idx = Comparison.findIndex(a => a.key === 'None');
const none = Comparison.splice(idx, 1);
Comparison.sort((a, b) => a.key.localeCompare(b.key));
Comparison.splice(0,0, none[0]);

console.log(Comparison);

Pour éviter tout problème d'élément spécial ou multiple:

var Comparison = [{ key: "None", value: "None" }, { key: "Geographical Area",value: "Geographical_Area" }, { key: "Forests", value: "Forests" }, { key: "Barren Unculturable Land", value: "Barren_Unculturable_Land" }, { key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use" }, { key: "Land Area", value: "Land_Area" }, { key: "Water Area", value: "Water_Area" }, { key: "Culturable Waste", value: "Culturable_Waste" }, { key: "Permanent Pastures", value: "Permanent_Pastures" }, { key: "Land under Tree Crops", value: "Land_under_Tree_Crops" }, { key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow" }, { key: "Current Fallow", value: "Current_Fallow" }, { key: "Total Unculturable Land", value: "Total_Unculturable_Land" }, { key: "Net Sown Area", value: "Net_Sown_Area" }, { key: "Gross Sown Area", value: "Gross_Sown_Area" }, { key: "Cropping Intensity", value: "Cropping_Intensity" },];

const obj = Comparison.reduce((acc, a) => {
  if (a.key === 'None') {
    acc.f.Push(a);
  } else {
    const idx = acc.s.findIndex(b => b.key.localeCompare(a.key) > 0);
    acc.s.splice(idx === -1 ? acc.s.length : idx, 0, a);
  }
  return acc;
}, { f: [], s: [] });

const res = obj.f.concat(obj.s);

console.log(res);
8
Hikmat G.

Vous pouvez également filtrer les nones et trier les autres éléments. Ensuite, enchaînez-les à la fin.

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

let result = comparison
             .filter(e => e.key === 'None')
             .concat(
               comparison.filter(e => e.key !== 'None')
                         .sort((a, b) => a.key.localeCompare(b.key))
             );
               
console.log(result);

Explication:

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

// fetch all elements with the key 'None'
let nones = comparison.filter(e => e.key === 'None');
// fetch all elements with the key not 'None'
let others = comparison.filter(e => e.key !== 'None')
// sort the elements in the array by key
                       .sort((a, b) => a.key.localeCompare(b.key));
// concatenate the 2 arrays together
let result = nones.concat(others);

console.log(result);

Un peu de crédit à réponse Pac0s . Après avoir écrit ma solution, j'ai vu que j'avais essentiellement fait une version de travail de son explication. Je suis trop tard pour ajouter mon exemple à sa réponse car c'est actuellement la plus appréciée des deux.

7
3limin4t0r

Il pourrait y avoir une meilleure approche, mais cela devrait fonctionner:

  1. Filtrez la valeur spéciale de votre tableau.

  2. Triez votre tableau sans la valeur spéciale.

  3. Réinsérez la valeur spéciale dans le tableau.

Pour un bon exemple de travail, voir @ Réponse de Johan Wentholt !

6
Pac0

Vous pouvez utiliser reduce pour obtenir la sortie souhaitée:

var Comparison = [{key:"Geographical Area", value:"Geographical_Area"},   {key:"Forests", value:"Forests"},   {key:"Barren Unculturable Land", value:"Barren_Unculturable_Land"}, {key: "None", value: "None"},  {key:"Land put to Non agricultural use", value:"Land_put_to_Non_agricultural_use"}, {key:"Land Area", value:"Land_Area"},   {key:"Water Area", value:"Water_Area"}, {key:"Culturable Waste", value:"Culturable_Waste"}, {key:"Permanent Pastures", value:"Permanent_Pastures"}, {key:"Land under Tree Crops", value:"Land_under_Tree_Crops"},   {key:"Fallow Land excl Current Fallow", value:"Fallow_Land_excl_Current_Fallow"},   {key:"Current Fallow", value:"Current_Fallow"}, {key:"Total Unculturable Land", value:"Total_Unculturable_Land"},   {key:"Net Sown Area", value:"Net_Sown_Area"},   {key:"Gross Sown Area", value:"Gross_Sown_Area"},   {key:"Cropping Intensity", value:"Cropping_Intensity"},]

var Comparison_sort = Comparison
                      .sort((a, b) => a.key.localeCompare(b.key))
                      .reduce((acc, e) => {
                        e.key === 'None' ? acc.unshift(e) : acc.Push(e);
                        return acc;
                      }, []);

console.log(Comparison_sort);

Trier à l'aide de reduce version-2:

let comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

var {Comparison_sort} = comparison.reduce((acc, obj, idx, arr) => {
                                  obj.key === 'None' ? acc['first'].Push(obj) : acc['last'].Push(obj)
                                  if (idx === arr.length - 1) (acc['last'].sort((a, b) => a.key.localeCompare(b.key)), acc['Comparison_sort'] = [...acc['first'], ...acc['last']])
                                  return acc
                                }, {first: [], last: [], Comparison_sort: []})

console.log(Comparison_sort);
3
BlackBeard

Une simple ligne: si l'une des clés de Array.prototype.sort la fonction de comparaison est 'Aucune', mettez-la toujours en haut, sinon faites une comparaison de base des clés avec String.prototype.localeCompare() :

var comparison = [{key: "None", value: "None"}, {key: "Geographical Area", value: "Geographical_Area"}, {key: "Forests", value: "Forests"}, {key: "Barren Unculturable Land", value: "Barren_Unculturable_Land"}, {key: "Land put to Non agricultural use", value: "Land_put_to_Non_agricultural_use"}, {key: "Land Area", value: "Land_Area"}, {key: "Water Area", value: "Water_Area"}, {key: "Culturable Waste", value: "Culturable_Waste"}, {key: "Permanent Pastures", value: "Permanent_Pastures"}, {key: "Land under Tree Crops", value: "Land_under_Tree_Crops"}, {key: "Fallow Land excl Current Fallow", value: "Fallow_Land_excl_Current_Fallow"}, {key: "Current Fallow", value: "Current_Fallow"}, {key: "Total Unculturable Land", value: "Total_Unculturable_Land"}, {key: "Net Sown Area", value: "Net_Sown_Area"}, {key: "Gross Sown Area", value: "Gross_Sown_Area"}, {key: "Cropping Intensity", value: "Cropping_Intensity"}];

var sorted = comparison.sort((a,b) => a.key === 'None' ? -1 : b.key === 'None' ? 1 : a.key.localeCompare(b.key));

console.log(sorted);
2
Leonid Pyrlia

La fonction <Array>.sort Prend un rappel comme argument. Ce rappel recevra deux valeurs. Le travail du rappel est de déterminer lequel est le plus grand. Il le fait en renvoyant une valeur numérique.

Supposons que les arguments passés à votre rappel s'appellent a et b. J'ai mis en gras les valeurs que votre rappel doit renvoyer pour chaque cas

  • a < bMoins de
  • a > bsupérieur à
  • a = bégal à

Ceci est facile à retenir car, pour les valeurs numériques, vous pouvez utiliser a - b Pour obtenir la valeur de retour souhaitée.

Maintenant, malgré la plupart des rappels passés à .sort Sont très petits, il est possible de passer des fonctions très compliquées pour répondre à vos besoins. Dans ce cas,

  • Si a.key Est Aucun, a < b
  • Si b.key Est Aucun, b < a
  • Sinon, utilisez notre mécanisme de tri actuel.

Nous pourrions profiter de la fermeture de l'instruction return une fois qu'elle est appelée. Donc, implémentons cette fonction puce par puce.

Pour rendre notre code super bon, retournons "0" lorsque les deux valeurs sont égales (même lorsque ces deux valeurs ont des clés "Aucune")

Comparison.sort(function(a, b) {
  // Our extra code
  if(a.key === b.key) return 0; // Zero (a = b)
  if(a.key === "None") return -1; // Negative (a < b)
  if(b.key === "None") return 1; // Positive (b < a)

  // Old sort
  if(a.key < b.key) return -1;
  if(b.key < a.key) return 1;  
})

Jouer au golf cette solution

Il existe des moyens de raccourcir cette solution (et, peut-être, de la rendre plus lisible) - ce qui est important lorsque le code effectue des tâches simples.

La première chose à noter est que la dernière ligne, if(b.key < a.key) return -1 pourrait être raccourcie en return -1;. En effet, si a.key < b.key Ou b.key = a.key Nous serions revenus sur une ligne antérieure.

La deuxième chose à noter est qu'en utilisant la syntaxe ES6 (qui pourrait ne pas être compatible avec les navigateurs plus anciens, en particulier concernant Internet Explorer), nous pouvons utiliser la notation de la fonction flèche pour le rappel.

function(a, b) {} pourrait devenir (a, b) => {}

La troisième chose à noter est que nous pouvons convertir le bloc de code ci-dessous

if(a.key < b.key) return -1;
if(b.key < a.key) return 1;

dans

return (b.key < a.key) - (a.key < b.key)

C'est parce que true est traité comme 1 Et false comme 0 En ce qui concerne la soustraction. true - false Est 1 - 0 Est 1, false - true Est 0 - 1 Est -1 Et 0 - 0 Est 0. Il n'y aura jamais de situation où true - true Se produira.

1
Max

Ajoutez simplement un chèque au début. S'il s'agit de l'objet none, déplacez-le vers l'avant sans effectuer les vérifications.

var Comparison_sort = this.Comparison.sort(function (a, b) {
    if (a.key == "None" && a.value == "None")
        return -1;
    if (b.key == "None" && b.value == "None")
        return 1;
    if (a.key < b.key)
            return -1;
    if (a.key > b.key)
            return 1;
    return 0;
});
1
Aplet123