À partir de cette question d'origine , comment appliquer un tri sur plusieurs champs?
En utilisant cette structure légèrement adaptée, comment puis-je trier la ville (croissant) et ensuite le prix (décroissant)?
var homes = [
{"h_id":"3",
"city":"Dallas",
"state":"TX",
"zip":"75201",
"price":"162500"},
{"h_id":"4",
"city":"Bevery Hills",
"state":"CA",
"zip":"90210",
"price":"319250"},
{"h_id":"6",
"city":"Dallas",
"state":"TX",
"zip":"75000",
"price":"556699"},
{"h_id":"5",
"city":"New York",
"state":"NY",
"zip":"00010",
"price":"962500"}
];
J'ai aimé le fait qu'une réponse a été donnée qui a fourni une approche générale. Là où je prévois d'utiliser ce code, je devrai trier les dates ainsi que d'autres choses. La capacité à «amorcer» l'objet semblait pratique, sinon un peu encombrante.
J'ai essayé de transformer cette réponse en un bel exemple générique, mais je n'ai pas beaucoup de chance.
javascript
arrays
sorting
Mike
la source
la source
sort(["first-field", "ASC"], ["second-field", "DSC"]);
c'est encore plus compliqué lorsque j'essaie d'ajouter la logique «d'amorce» de la première réponse afin de pouvoir gérer les dates, l'insensibilité à la casse, etc.Réponses:
Une méthode de tri multidimensionnelle, basée sur cette réponse :
Mise à jour : Voici une version "optimisée". Il fait beaucoup plus de prétraitement et crée au préalable une fonction de comparaison pour chaque option de tri. Il peut avoir besoin de plus de mémoire (car il stocke une fonction pour chaque option de tri, mais il devrait se préformer un peu mieux car il n'a pas à déterminer les paramètres corrects lors de la comparaison. Je n'ai cependant pas fait de profilage).
Exemple d'utilisation:
DEMO
Fonction d'origine:
DEMO
la source
pour une solution simple et non générique à votre problème exact:
la source
if
instruction n'a aucun sens.a.localeCompare(b)
dans la dernière ligne pour la comparaison de chaîne ... voir la documentationif (a.city === b.city)
? Autrement dit, si les deux villes sont identiques, comparez les prix, sinon comparez les villes.Vous pouvez utiliser une approche de tri chaîné en prenant le delta des valeurs jusqu'à ce qu'il atteigne une valeur différente de zéro.
Ou, en utilisant es6, simplement:
la source
Voici une approche fonctionnelle simple. Spécifiez l'ordre de tri à l'aide du tableau. Ajoutez moins pour spécifier l'ordre décroissant.
Edit: dans ES6 c'est encore plus court!
la source
[10,100,11,9]
. Ai-je oublié quelque chose?J'ai fait aujourd'hui un trieur multifonction assez générique. Vous pouvez consulter thenBy.js ici: https://github.com/Teun/thenBy.js
Il vous permet d'utiliser le standard Array.sort, mais avec le style firstBy (). ThenBy (). ThenBy (). C'est beaucoup moins de code et de complexité que les solutions affichées ci-dessus.
la source
La fonction suivante vous permettra de trier un tableau d'objets sur une ou plusieurs propriétés, par ordre croissant (par défaut) ou décroissant sur chaque propriété, et vous permettra de choisir d'effectuer ou non des comparaisons sensibles à la casse. Par défaut, cette fonction effectue des tris insensibles à la casse.
Le premier argument doit être le tableau contenant les objets. Le ou les arguments suivants doivent être une liste de chaînes séparées par des virgules qui référencent les différentes propriétés d'objet à trier. Le dernier argument (qui est facultatif) est un booléen pour choisir d'effectuer ou non des tris sensibles à la casse - à utiliser
true
pour les tris sensibles à la casse.La fonction triera chaque propriété / clé par ordre croissant par défaut. Si vous voulez une clé particulière pour trier par ordre décroissant, puis passer à la place dans un tableau dans ce format:
['property_name', true]
.Voici quelques exemples d'utilisation de la fonction suivis d'une explication (où se
homes
trouve un tableau contenant les objets):objSort(homes, 'city')
-> trier par ville (croissant, sensible à la casse)objSort(homes, ['city', true])
-> trier par ville (décroissant, sensible à la casse)objSort(homes, 'city', true)
-> trier par ville puis prix (croissant, sensible à la casse )objSort(homes, 'city', 'price')
-> trier par ville puis prix (à la fois croissant, sensible à la casse)objSort(homes, 'city', ['price', true])
-> trier par ville (croissant) puis prix (décroissant), sensible à la casse)Et sans plus tarder, voici la fonction:
Et voici quelques exemples de données:
la source
C'est une triche complète, mais je pense que cela ajoute de la valeur à cette question car il s'agit essentiellement d'une fonction de bibliothèque prédéfinie que vous pouvez utiliser prête à l'emploi.
Si votre code a accès à
lodash
ou à une bibliothèque compatible avec lodash,underscore
vous pouvez utiliser la_.sortBy
méthode. L'extrait ci-dessous est copié directement à partir de la documentation de lodash .Les résultats commentés dans les exemples semblent renvoyer des tableaux de tableaux, mais cela montre simplement l'ordre et non les résultats réels qui sont un tableau d'objets.
la source
En voici un autre qui est peut-être plus proche de votre idée de la syntaxe
Démo: http://jsfiddle.net/Nq4dk/2/
Edit: Juste pour le plaisir, voici une variation qui prend juste une chaîne de type SQL, donc vous pouvez le faire
sortObjects(homes, "city, price desc")
la source
Plus simple:
la source
J'aime l'approche de SnowBurnt, mais il faut un ajustement pour tester l'équivalence sur la ville PAS une différence.
la source
Voici un tri multidimensionnel générique, permettant l'inversion et / ou le mappage à chaque niveau.
Écrit en tapuscrit. Pour Javascript, consultez ce JSFiddle
Le code
Exemples d'utilisation
Trier un tableau de personnes par nom de famille, puis par prénom:
Triez les codes de langue par leur nom , pas leur code de langue (voir
map
), puis par version décroissante (voirreverse
).la source
Une façon dynamique de faire cela avec PLUSIEURS touches:
Utilisation:
la source
Voici une version générique de la solution de @ Snowburnt:
Ceci est basé sur une routine de tri que j'utilise. Je n'ai pas testé ce code spécifique, il peut donc contenir des erreurs, mais vous voyez l'idée. L'idée est de trier en fonction du premier champ qui indique une différence, puis de s'arrêter et de passer à l'enregistrement suivant. Donc, si vous triez selon trois champs et que le premier champ de la comparaison est suffisant pour déterminer l'ordre de tri des deux enregistrements en cours de tri, renvoyez ce résultat de tri et passez à l'enregistrement suivant.
Je l'ai testé (en fait avec une logique de tri un peu plus complexe) sur 5000 disques et il l'a fait en un clin d'œil. Si vous chargez réellement plus de 1000 enregistrements sur le client, vous devriez probablement utiliser le tri et le filtrage côté serveur.
Ce code ne gère pas la casse mais je laisse au lecteur le soin de gérer cette modification triviale.
la source
Voici ma solution basée sur l' idiome de transformation Schwartzian , j'espère que vous la trouverez utile.
Voici un exemple comment l'utiliser:
la source
Autrement
la source
Comment utiliser (mettre - (moins) signe avant le champ si vous souhaitez trier par ordre décroissant un champ particulier)
En utilisant la fonction ci-dessus, vous pouvez trier n'importe quel tableau json avec plusieurs champs. Pas besoin de changer de corps de fonction du tout
la source
Adaptation de la réponse de @chriskelly.
La plupart des réponses oublient que le prix ne sera pas trié correctement si la valeur se situe dans les dizaines de milliers et moins ou plus d'un million. La resaon étant JS trie par ordre alphabétique. Il a été répondu assez bien ici, Pourquoi JavaScript ne peut pas trier "5, 10, 1" et ici Comment trier correctement un tableau d'entiers .
En fin de compte, nous devons faire une évaluation si le champ ou le nœud sur lequel nous trions est un nombre. Je ne dis pas que l'utilisation
parseInt()
dans ce cas est la bonne réponse, les résultats triés sont plus importants.Un violon à tester
la source
price
dans l'exemple est au format chaîne. Si vous voulez que cela fonctionne correctement avec mon exemple, utilisez map pour convertir d'abord le champ que vous souhaitez en format numérique. ieconst correctedHomes = homes.map(h => ({...h, price: +h.price}))
Wow, il y a des solutions complexes ici. Si complexe, j'ai décidé de proposer quelque chose de plus simple mais aussi assez puissant. C'est ici;
Et voici un exemple de la façon dont vous l'utilisez.
Cela triera d'abord par ordre de priorité des attributs, puis par valeur des attributs.
la source
Voici un moyen extensible de trier par plusieurs champs.
Remarques
a.localeCompare(b)
est universellement supporté et retourne -1,0,1 sia<b
,a==b
,a>b
respectivement.||
dans la dernière ligne donne lacity
priorité surprice
.-price_order
var date_order = new Date(left.date) - new Date(right.date);
fonctionne comme numerics parce que les mathématiques date se transforme en millisecondes depuis 1970.return city_order || -price_order || date_order;
la source
Je pense que c'est peut-être le moyen le plus simple de le faire.
https://coderwall.com/p/ebqhca/javascript-sort-by-two-fields
C'est vraiment simple et je l'ai essayé avec 3 paires de valeurs clés différentes et cela a très bien fonctionné.
Voici un exemple simple, regardez le lien pour plus de détails
la source
Voici le mien pour votre référence, avec exemple:
la source
Je cherchais quelque chose de similaire et j'ai fini avec ceci:
Tout d'abord, nous avons une ou plusieurs fonctions de tri, renvoyant toujours 0, 1 ou -1:
Vous pouvez créer plus de fonctions pour chaque autre propriété sur laquelle vous souhaitez trier.
Ensuite, j'ai une fonction qui combine ces fonctions de tri en une seule:
Cela peut être utilisé pour combiner les fonctions de tri ci-dessus de manière lisible:
Lorsqu'une fonction de tri renvoie 0, la fonction de tri suivante sera appelée pour un tri ultérieur.
la source
Juste une autre option. Pensez à utiliser la fonction utilitaire suivante:
Exemple d'utilisation (dans votre cas):
Il est à noter que cette fonction peut être encore plus généralisée afin de pouvoir utiliser des propriétés imbriquées comme 'address.city' ou 'style.size.width' etc.
la source
Il s'agit d'un algorithme récursif permettant de trier par plusieurs champs tout en ayant la possibilité de formater les valeurs avant comparaison.
Si a et b sont égaux, il essaiera simplement le champ suivant jusqu'à ce qu'aucun ne soit disponible.
la source
la source
Ici, «AffiliateDueDate» et «Title» sont des colonnes, les deux sont triées par ordre croissant.
la source
Tri sur deux champs de date et un exemple de champ numérique:
http://jsfiddle.net/hcWgf/57/
la source
En utilisant :
Afficher l'extrait de code
la source
Que diriez-vous de cette solution simple:
Basé sur cette question, javascript trie le tableau par plusieurs champs (nombre)
la source