Comptage de valeurs distinctes

J’ai une collection avec des valeurs répétées, je veux en tirer les valeurs distinctes tout en les comptant :
<code 4D>
C_COLLECTION($coll_c)
$coll_c:=Créer collection(“a”;“a”;“a”;“b”;“b”;“c”)
$distinct_c:=Créer collection
Pour chaque ($value_t;$coll_c.distinct())
$distinct_c.push(Créer objet(“value”;$value_t;“count”;Chaîne($coll_c.countValues($value_t))))
Fin de chaque
</code 4D>

Question similaire avec ORDA ; par exemple j’ai des clients et des factures, je voudrais une collection de clients avec le nombre de factures de chaque.

J’ai l’impression de passer à coté d’un truc plus simple avec countValues et distinct : il y a mieux que la boucle ci-dessus ?

Salut,

Je ne sais ps si c’est mieux (son quel point de vue, performance, simplicité code, lisibilité, etc…), mais en SQL, tu peux faire

SELECT maCol, COUNT(*) FROM maTable GROUP BY maCol

A+

Tu peux faire un tableau associatif sinon. C’est plus rapide.
<code 4D>
C_COLLECTION($coll_c;$distinct_c)
C_ENTIER LONG($i;$nb;$tps1;$tps2)
C_OBJET($decompte)
C_TEXTE($value_t;$valeurs)
$nb:=10000
$valeurs:=“abcdefghijklmnopqrstuvwxyz”
Repeter
$nb:=Num(Demander(“Nombre de valeurs :”;Chaîne($nb)))
Si (OK=1)
$coll_c:=Créer collection
Boucle ($i;1;$nb)
$coll_c.push($valeurs[Hasard%Longueur($valeurs)+1])
Fin de boucle

		$tps1:=Nombre de millisecondes
		$decompte:=Créer objet
		Pour chaque ($value_t;$coll_c)
			Si ($decompte[$value_t]=Null)
				$decompte[$value_t]:=1
			Sinon 
				$decompte[$value_t]:=$decompte[$value_t]+1
			Fin de si 
		Fin de chaque 
		$tps1:=Nombre de millisecondes-$tps1
		
		$tps2:=Nombre de millisecondes
		$distinct_c:=Créer collection
		Pour chaque ($value_t;$coll_c.distinct())
			$distinct_c.push(Créer objet("value";$value_t;"count";Chaîne($coll_c.countValues($value_t))))
		Fin de chaque 
		$tps2:=Nombre de millisecondes-$tps2
		
		ALERTE("Tableau associatif : "+Chaîne($tps1)+"\rValeurs distinctes : "+Chaîne($tps2))
	Fin de si 
Jusque (OK=0)

</code 4D>

à tout deux,
merci, d’abord. En SQL je savais faire, c’est très lisible, mais ça ne marche que si j’attaque les données. Quand la question s’est posée j’étais avec une collection (mémoire). Je ne recherche pas la performance, non plus, c’est juste pour savoir si un assemblage savant de member functions, de points et de parenthèses permet de faire “distinct avec count” sur une ligne, sans le “Pour chaque”.

Bonsoir Arnaud,

pour moi, ton approche est bonne et si j’avais à le faire j’aurai très certainement pondu un bout de code comme le tien.

Patrick

En réalité j’ai un cas de conscience à chaque fois que j’écris Pour chaque, ça n’a pas la classe de For each.

un passage en douceur de Français à Franglais pour finir en Anglais devrait faire l’affaire :wink:

Tant que j’ai des versions < 15, ça n’est pas terrible. Mais il est prévu d’aller vers la douceur. Doucement.

Bonjour Arnaud,

Pour la question ORDA, comment est le lien entre clients et factures ?

Dans le cas d’un lien one to many de clients vers factures qui se nomme “factures”:

Vous pouvez faire une query sur la table clients, puis avoir le nombre de factures sur chaque client: avec factures.length ?

Bonjour Marie-Sophie,
bonne idée, il faut que j’essaie. Mais, à première vue, ce ne sera pas aussi “direct” que le SQL. Ce “distinct with count” est un besoin que je retrouve souvent.

: Patrick EMANUEL

un passage en douceur de Français à Franglais pour finir en Anglais
Tu parles d’une douceur…
Ou comment réduire ma dette technique avec un langage qui en trimballe une bonne.

TOUT SELECTIONNER • ALL RECORDS
CREER ENREGISTREMENT • CREATE RECORD
Nouvelle liste • New list
Nouvel enregistrement • Is new record
Creer collection • New collection
Creer objet • New object
Nouveau process • New process
Numero du process courant • Current process
Chercher process • Process number
TUER PROCESS PAR ID • ABORT PROCESS BY ID
SUPPRIMER DANS LISTE • DELETE FROM LIST
SUPPRIMER MESSAGES • MESSAGES OFF
Est un numero de table valide • Is table number valid

Croire qu’on peut trouver la commande en anglais quand on connait par :heart: son nom français avec des rudiments d’anglais est source régulière de perte de temps et d’énervement : on peut se faire avoir par le verbe (créer - new), par une préposition (dans - from), par les deux (supprimer - off), par des sens totalement différents (Chercher process - Process number) et ainsi de suite. Je comprends mieux pourquoi Vincent a fait un utilitaire pour traduire à la volée, me console avec https://www.youtube.com/watch?v=l3t45eltOaoMolière> et me dit que tout serait si simple si le chapitre était en préfixe et si l’on s’inspirait de la notation à points ! :cry:

: Arnaud DE MONTARD

Croire qu’on peut trouver la commande en anglais quand on connait par
:heart: son nom français avec des rudiments d’anglais est source régulière
de perte de temps et d’énervement…

Hé oui, c’est aussi pourquoi tu as dans QS_Toolbox un traducteur :wink:
C’est pour éviter ce genre de désagrément, entre autre

Il y a un fichier de macros pour faire le passage en https://github.com/vdelachaux/macrosdouceur> :wink:

Comme c’est apparenté, que personne ne l’a évoqué dans ce fil et que je n’ai appris ça qu’hier :oops: :
https://livedoc.4d.com/4D-Langage-15-R4/Tableaux/VALEURS-DISTINCTES.301-2825096.fr.htmlVALEURS DISTINCTES> accepte un 3ème argument… depuis la v15r4.

Oula, Arnaud ça devient grave :roll:
On en a parlé https://forums.4d.com/Post/FR/32483239/3/32553055#32511100ici> et tu fais parti de la discussion :!:

AH AAAAHHHHHH ! tu es démasqué, la preuve que tu nous lis en diagonale est faite… :lol: