Page 1 sur 1
[RESOLU] Tri sur plus d'un champ (List)
Publié : lun. 15/janv./2018 18:18
par omega
Bonjour à tous,
Est-il possible de trier une liste chaînée sur 2 champs en même temps ? Exemple sur nom,matricule (tri sur le nom puis sur matricule)
Pour trier sur un champ, le code est le suivant:
Code : Tout sélectionner
SortStructuredList(Maliste(), #PB_Sort_Ascending|#PB_Sort_NoCase, OffsetOf(MalisteStr\nom), #PB_Sort_String)
Merci
Re: Tri sur plus d'un champ (List)
Publié : lun. 15/janv./2018 18:51
par falsam
Re: Tri sur plus d'un champ (List)
Publié : lun. 15/janv./2018 19:05
par falsam
Si tu ne souhaites pas utiliser une variable de regroupement alors tu as le
tri fusion en natif dans PureBasic depuis la version 4.30.
Code : Tout sélectionner
Structure Test
Champs1.s
Champs2.s
EndStructure
NewList Tableau.Test()
AddElement(Tableau())
With Tableau()
\Champs1 = "Legumes"
\Champs2 = "Tomates"
EndWith
AddElement(Tableau())
With Tableau()
\Champs1 = "Fruits"
\Champs2 = "Oranges"
EndWith
AddElement(Tableau())
With Tableau()
\Champs1 = "Fruits"
\Champs2 = "Abricots"
EndWith
AddElement(Tableau())
With Tableau()
\Champs1 = "Legumes"
\Champs2 = "Pommes de terre"
EndWith
AddElement(Tableau())
With Tableau()
\Champs1 = "Fruits"
\Champs2 = "Papaye"
EndWith
AddElement(Tableau())
With Tableau()
\Champs1 = "Legumes"
\Champs2 = "Courgettes"
EndWith
;Tri par famille et par produit
SortStructuredList(Tableau(), #PB_Sort_Ascending, OffsetOf(Test\Champs2), #PB_String) ;Produits en premier
SortStructuredList(Tableau(), #PB_Sort_Ascending, OffsetOf(Test\Champs1), #PB_String) ;Famille en dernier
ForEach Tableau()
Debug Tableau()\Champs1 + " - " + Tableau()\Champs2
Next
Re: Tri sur plus d'un champ (List)
Publié : mar. 16/janv./2018 18:39
par omega
Bonjour Falsam et merci pour ces 2 codes. Le 1er concerne un tableau et non pas une liste chaînée mais bon dans les 2 cas (les 2 exemples de code), il s'agit finalement de regrouper 2 ou 3 champs ensembles. C'est effectivement une solution mais il y a un mais:
Cette solution marche dans le cas où je connais les champs à trier, c'est à dire que le tri concerne toujours 2 champs bien définis et connus, exemple Nom et matricule... Mais quand il s'agit de choisir entre plusieurs champs (une dizaine par exemple, comme c'est mon cas) alors il va falloir modifier le contenu de la clé à chaque fois que l'utilisateur change d'argument de tri. Je m'explique (et dis moi si je ne déconne pas) :
Structure ClientStr
Nom.s
Tel.s
adresse.s
profession.s
age.i
sexe.s
Salaire.q
CleTri.s
EndStructure
Si l'utilisateur choisit le tri suivant: Nom, telephone
Je dois parcourir la liste pour mettre à jour le contenu de la clé comme suit:
CleTri=nom$ + space(1) + Tel$
et je trie sur CleTri
Si l'utilisateur choisit le tri suivant: Sexe,Nom
Je dois parcourir la liste pour mettre à jour le contenu de la clé comme suit:
CleTri=sexe$ + space(1) + nom$
et je trie sur CleTri
etc...
Donc la mise à jour du contenu de la cle se fait à chaque fois que l'utilisateur change d'argument de tri
Est ce que c'est correct Falsam?
Merci beaucoup
Re: Tri sur plus d'un champ (List)
Publié : mar. 16/janv./2018 19:54
par Ar-S
Pour ce genre de trie une base sqlite serait surement bien plus adéquate non ? Tu as pas mal d'exemple sur le forum.
Re: Tri sur plus d'un champ (List)
Publié : mar. 16/janv./2018 20:40
par omega
Non Ar-s, c'est trop lent avec sqlite, même dans ce cas là, il faut retrier la table à chaque fois en fonction des arguments. J'ai déjà essayé et ça prend 100 fois plus de temps qu'une liste chaînée.
Re: Tri sur plus d'un champ (List)
Publié : mar. 16/janv./2018 22:55
par Ar-S
OK...
Tu utilises les listes, tu aurais du opter pour les Map et / ou tableau mais bon...
Voilà mon astuce pour rester dans ton optique de codage.
En gros ta clé trie ne sert pas. Tu as ordre pré établie dans ta structure et tu souhaites le trier dans l'ordre que tu veux.. Voilà comment je procèderai.
Code : Tout sélectionner
Structure ClientStr
Nom.s ; 1
Tel.s ; 2
adresse.s ; 3
profession.s ; 4
age.s ; 5
sexe.s ; 6
Salaire.s ; 7
EndStructure
; La liste qui va stocker les infos structurées
Global NewList TousLesChamps.ClientStr()
; La liste qui va stocker ligne par lignes les infos clients le tout séparé par une virgule
Global NewList Client.s()
Macro AddClient(M_Nom, M_Tel, M_Adresse, M_Prof, M_age, M_Sexe, M_salaire)
; Ar-S
; On stock tous les champs dans une simple liste structurée
AddElement (TousLesChamps() )
TousLesChamps.ClientStr\Nom = M_Nom
TousLesChamps\Tel = M_Tel
TousLesChamps\adresse = M_Adresse
TousLesChamps\profession= M_Prof
TousLesChamps\age = M_age
TousLesChamps\sexe = M_Sexe
TousLesChamps\Salaire = M_salaire
; stockage ligne par lignes des infos clients le tout séparé par une virgule
AddElement( Client() )
Client() = TousLesChamps\Nom.s +","+TousLesChamps\Tel.s+","+TousLesChamps\Adresse.s +","+ TousLesChamps\profession.s +","+ TousLesChamps\age.s +","+ TousLesChamps\sexe.s +","+ TousLesChamps\Salaire.s
EndMacro
Macro TrieClient(Champ1,Champ2,Champ3,Champ4,Champ5,Champ6,Champ7)
;Ar-S
; La macro qui va servir à trier selon le numéro des champs
ForEach Client()
Ligne.s = Client()
El1.s = StringField(Ligne.s,Champ1,",")
El2.s = StringField(Ligne.s,Champ2,",")
El3.s = StringField(Ligne.s,Champ3,",")
El4.s = StringField(Ligne.s,Champ4,",")
El5.s = StringField(Ligne.s,Champ5,",")
El6.s = StringField(Ligne.s,Champ6,",")
El7.s = StringField(Ligne.s,Champ7,",")
; C'est cette NewLigne.s que tu remplaceras par une nouvelle liste chainée (faut bien que tu bosses un peu)
NewLigne.s = El1 + Space(1) + El2 + Space(1) + El3 + Space(1) + El4 + Space(1) + El5 + Space(1) + El6 + Space(1) + El7
Debug NewLigne
Next
EndMacro
; ///////////////////////////////////////////////////
; /////////////////// PROG //////////////////////////
; ///////////////////////////////////////////////////
; Ajoute client 1
AddClient("Ar-S", "06.06.06.06.06", "Rue du zbouel", "informaticien", "42", "rose", "1400")
; Ajoute client 2
AddClient("Omega", "07.07.07.07.07", "Rue du zboubi", "codeur", "30", "autre", "1800")
; Affichage standard
Debug "/////// Affichage standard //////////"
ForEach Client()
Debug Client()
Next
Debug ""
Debug "/////// Affichage trié //////////"
;Je trie selon un ordre désiré
TrieClient(1,7,2,3,5,4,6) ; Tri Nom Salaire Tel Adresse Age Prof Sexe
Re: Tri sur plus d'un champ (List)
Publié : mar. 16/janv./2018 23:19
par falsam
omega a écrit :Si l'utilisateur choisit le tri suivant: Nom, telephone
Je dois parcourir la liste pour mettre à jour le contenu de la clé comme suit:
CleTri=nom$ + space(1) + Tel$
et je trie sur CleTri
Si l'utilisateur choisit le tri suivant: Sexe,Nom
Je dois parcourir la liste pour mettre à jour le contenu de la clé comme suit:
CleTri=sexe$ + space(1) + nom$
et je trie sur CleTri
etc...
Donc la mise à jour du contenu de la cle se fait à chaque fois que l'utilisateur change d'argument de tri
Est ce que c'est correct Falsam?
Presque correct ....
Tu dois formater chacune de tes variables dans la variable de regroupement avec la fonction LSet()
Au lieu de
utilises à la place
Je pense qu'utiliser une base de données SQLite
en mémoire serait plus adéquate pour trier des données.
Créer une base de données en mémoiresi tu sais manipuler une base de données SQLite, tu dois savoir utiliser la clause
ORDER dans une sélection de d'enregistrements.
Re: Tri sur plus d'un champ (List)
Publié : mer. 17/janv./2018 11:32
par microdevweb
Il est également possible de faire un tableau trié contenant les adresses de la liste.
Voici plusieurs méthodes de tri
http://www.purebasic.fr/french/viewtopi ... 21&t=16420
Re: Tri sur plus d'un champ (List)
Publié : mer. 17/janv./2018 14:03
par omega
Merci à vous tous pour votre aide
@A-rs
Je vais tester ta deuxième proposition et j'y reviendrais
@Falsam
Si tu es sûr qu'une base de données sqlite en mémoire est plus rapide qu'une liste chaînée, j'aimerais bien utiliser cette solution, car j'utilise une base sqlite (sur disque) et j'ai constaté que la relecture d'une table (à chaque nouveau tri) prend beaucoup de temps car il s'agit d'afficher plus de 8000 lignes sur une listIconGadget. Autrement dit, si l'utilisateur change l'argument de tri, ces 8000 lignes doivent être Retriées selon les nouveaux arguments et réaffichées sur ListIconGadget. Si je retrie la table et la réaffiche cela prend énormément de temps par rapport à une liste chainée.
Ma question: Une base en mémoire serait elle plus efficace en matière de temps?
Dernière question: j'utilise très souvent la base sqlite (sur disque) mais jamais en mémoire.
Est ce que ce code suffit pour créer une base en mémoire?
Merci beaucoup
Re: Tri sur plus d'un champ (List)
Publié : mer. 17/janv./2018 14:57
par Mesa
Tri à bulle multichamps pour list et tableau d'après pappip.
http://www.purebasic.fr/french/viewtopi ... 2&start=30
M.
Re: Tri sur plus d'un champ (List)
Publié : lun. 05/févr./2018 20:04
par omega
Merci à vous tous ! plusieurs méthodes qui marchent ! Il va falloir choisir.
Merci encore et bonne continuation