Bonjour,
J'ai en nodejs et Typescript un get de forme :
Comment je peux traiter ? décomposer genre avoir un tabelau en découpant par ici "and" ?Code:[["exposant.raisonSociale","=","Alexandre"],"and",["etat","=","Terminé"]]
Merci
Version imprimable
Bonjour,
J'ai en nodejs et Typescript un get de forme :
Comment je peux traiter ? décomposer genre avoir un tabelau en découpant par ici "and" ?Code:[["exposant.raisonSociale","=","Alexandre"],"and",["etat","=","Terminé"]]
Merci
Curieux format, je me demande à quel besoin c’est censé répondre.
Ta question est un peu vague. Ton but est-il de transformer le tableau en une autre structure ? Ou de récupérer une info en particulier ? Ou de parcourir le tableau et d’appliquer un traitement en fonction des valeurs rencontrées ?
Pour commencer, je partirais sur une boucle for..of avec une détection de type légère :
Ce "and" me laisse penser qu’il pourrait aussi y avoir des "or" (et pourquoi pas des "not"), ce qui pourrait amener à des situations ambigües où l’usage des parenthèses deviendrait une nécessité. Dans ce cas, le format serait une sorte de micro-langage, et il faudrait mettre en œuvre un interpréteur.Code:
1
2
3
4
5
6
7
8
9 for (let item of tableauRecu) { if ("and" === item) { ... } else if (item instanceof Array) { ... } }
Par curiosité, d’où provient ce tableau ?
Cel viens en fait de l'outil DevExtreme exemple : https://js.devexpress.com/Demos/Widg...Angular/Light/
quand je filtre il envoi les données en GET et l'url de GET émis est du style :
C'est principalement pour les données en DataGrid gérer le filtre et retourner le résultat en donnant à Mysql (requête) les bon paramètres ...Code:&take=10&filter=[%22exposant.raisonSociale%22,%22=%22,%22Alexandre%22]
Merci
D’accord.
Du coup, quel est ton objectif ? De quelle façon veux-tu traiter ce tableau ?
Bonsoir,
Je crois j'ai trouver une solution peut être :
Es-ce la bonne solution ?Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 filter = JSON.parse(filter); filter = [...filter]; const filterSplitFirst = filter.toString().split(',and,'); filterSplitFirst.forEach(element => { const filterSplitSecond = element.replace(/,/g, '').split('='); const q = filterSplitSecond[0]; const operator = '='; const search = filterSplitSecond[1]; query.andWhere(q + ' ' + operator + ' :search', { search }); });
Pour être honnête, je trouve que les passages avec split manquent d’élégance. C’est peut-être plus court en lignes de code, mais d’un point de vue algorithmique, c’est plus complexe :
- toString sérialise le tableau en chaîne ;
- derrière, split convertit cette chaîne en un nouveau tableau,
- pendant ce temps, le tableau original est toujours en mémoire car il y a toujours la variable filter qui pointe dessus.
Donc cette façon de faire est gourmande à la fois en temps et en mémoire.
Il est possible de tout faire en une seule boucle. Voici comment je ferais :
:arrow: Pour commencer, tu n’as pas besoin de ... car la structure est déjà un tableau. Tu peux itérer directement dessus avec une boucle for..of comme dans mon exemple, ou avec la méthode forEach comme tu as fait.
:arrow: Ensuite, ignore simplement les items "and" quand tu les rencontres dans ta boucle.
:arrow: Enfin, je n’utiliserais pas split donc les sous-tableaux garderaient leur forme, donc pas besoin de replace. Tu pourrais donc accéder directement à element[0] et element[2], en supposant que les infos se présentent toujours sous la forme [ "machin", "=", "truc" ].
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 JSON.parse(filter).forEach((element) => { if ("and" === element) return; const q = element[0]; const operator = '='; const search = element[2]; console.log(`q = ${q}`); console.log(`operator = ${operator}`); console.log(`search = ${search}`); query.andWhere(`${q} ${operator} :search`, { search }); });
Bonsoir,
Je comprend ta démarche sauf que avec ton code plus logique dans le code me dort pas du tout ce qu'il faut.
Ici le filter = ["exposant.raisonSociale","=","Alexandre"]Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 JSON.parse(filter).forEach((element) => { console.log('element => ' + element); if ('and' === element) { return; } const q = element[0]; const operator = '='; const search = element[2]; console.log(`q = ${q}`); console.log(`operator = ${operator}`); console.log(`search = ${search}`); query.andWhere(`${q} ${operator} :search`, { search }); });
cela me donne en sortie :
Si je fait ne variable pour afficher la valeur de JSON.parse(filter), j'ai :Code:
1
2
3
4
5
6
7
8
9
10
11
12 element => exposant.raisonSociale q = e operator = = search = p element => = q = = operator = = search = undefined element => Alexandre q = A operator = = search = e
MerciCode:parsedFilter => exposant.raisonSociale,=,Alexandre
Bonjour,
En fait non c'est plus compliqué : je peux aussi avoir au maximum ce cas la :
Code:[[["exposant.raisonSociale","=","RAISON 2"],"or",["exposant.raisonSociale","=","EXP2"]],"and",[["etat","=","Affecté"],"or",["etat","=","En Cours"]]]
Merci
Je vois, c’est une structure récursive. Et à quoi devrait ressembler la requête finale avec ce filtre ?
Bonsoir,
la requête doit être, par exemple :
J'arrive a le faire quand je choisi ce format mais surement pas êcrit comme tu l'aurait fait, pas optimisé. Mais je galéré à le faire, je fait :Code:WHERE (`exposant`.`raison_sociale`='Paul' OR `exposant`.`raison_sociale`='Alexandre') AND (`reservations`.`etat`='Nouveau' OR `reservations`.`etat`='Affecté')
Attention la valeur du filtre envoyé est comme cela maintenant :
Code:exposant.raisonSociale,=,Paul Est Le Meilleur|and|etat,=,Affecté,or,etat,=,Nouveau
MerciCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 const filterSplitAnd = filter.toString().split('|and|'); console.log('TAILLE TABLEAU => ' + filterSplitAnd.length); filterSplitAnd.forEach(elementAnd => { query.andWhere(new Brackets(sqb => { console.log('elementAnd => ' + elementAnd); const filterSplitOr = elementAnd.toString().split(',or,'); filterSplitOr.forEach(elementOr => { console.log('elementOr => ' + elementOr); const elementEgal = elementOr.toString().split(',=,'); const q = elementEgal[0]; const operator = '='; const search = elementEgal[1]; console.log(' q => ' + q); console.log(' operator => ' + operator); console.log(' search => ' + search); let prefix = ''; if ( q.indexOf('.') === -1) { prefix = 'reservations.'; } sqb.orWhere(`${prefix}${q}${operator}'${search}'`); }); })); });
Bonjour,
Ta première formulation était finalement plus claire et "parlante" :
Les crochets symbolisant l'emplacement des parenthèses.Code:[[["exposant.raisonSociale","=","RAISON 2"],"or",["exposant.raisonSociale","=","EXP2"]],"and",[["etat","=","Affecté"],"or",["etat","=","En Cours"]]]
Une fois indenté, c'est plus flagrant :
On voit qu'à chaque niveau, on a un groupe de 3 éléments (elt[0],elt[1],elt[2]):Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 [ [ ["exposant.raisonSociale","=","RAISON 2"], "or", ["exposant.raisonSociale","=","EXP2"] ], "and", [ ["etat","=","Affecté"], "or", ["etat","=","En Cours"] ] ]
- soit l'élément central (elt[1]) est "and" ou "or" -> on a une structure avec des parenthèses ( [arr1] and/or [arr2] )
- soit l'élément central (elt[1]) est "=" ou "!=" ou (?) (autre chose que "and" ou "or") -> on concatène les 3
J'ai le cerveau un peu mou en ce moment.
Mais pour un spécialiste, ça ne devrait pas trop posé de problème.
Sans chercher midi à 14h.... avec quelques regex *
....et sans AUCUNE manipulation d'array compliquée ou récursive ou autre :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 function get_filter_sqlwhere( filter ) { // 1- on convertit en chaine de caractères var sqlwhere = JSON.stringify( filter ); // 2- on remplace les groupes, puis les caractères [ ] " et , sqlwhere = sqlwhere.replace(/\[\"([^\"\.]*)\",\"([^\"]*)\",\"([^\"]*)\"\]/gi, '`$1`$2\'$3\'' ); sqlwhere = sqlwhere.replace(/\[\"([^\"\.]*)(\.)([^\"\.]*)\",\"([^\"]*)\",\"([^\"]*)\"\]/gi, '`$1`$2`$3`$4\'$5\'' ); sqlwhere = sqlwhere.replace(/\[/gi,'('); sqlwhere = sqlwhere.replace(/\]/gi,')'); sqlwhere = sqlwhere.replace(/\"/gi,' '); sqlwhere = sqlwhere.replace(/,/gi,''); return ' WHERE ' + sqlwhere; }
Code:
1
2
3
4
5
6 var filter = [[["exposant.raisonSociale","=","RAISON 2"],"or",["exposant.raisonSociale","=","EXP2"]],"and",[["etat","=","Affecté"],"or",["etat","=","En Cours"]]]; console.log ( filter ); console.log ( JSON.stringify( filter ) ); // converti en chaine var sqlWHERE = get_filter_sqlwhere( filter ); console.log ( sqlWHERE );
On obtient la chaine :
Code:WHERE ((`exposant`.`raisonSociale`='RAISON 2' or `exposant`.`raisonSociale`='EXP2') and (`etat`='Affecté' or `etat`='En Cours'))
Je me trompe, ou c'est ce qu'on veut obtenir ? 8-)
* Je n'ai pas la maitrise suffisante en regex, du coup j'ai fait plusieurs passes (mais ça doit pouvoir s'optimiser).
Bonjour,
Moi cela me sort comme string :
sans les ( )Code:exposant.raisonSociale=Paul Est Le Meilleurorexposant.raisonSociale=Alexandreandetat=Nouveauoretat=Affecté
Merci
1- J'ai mis à jour mon précédent message.
2- ATTENTION : je pars de la structure de l'objet, tel que donné dans ton 1er message :
Évidemment, ça ne fonctionne pas avec :Code:[[["exposant.raisonSociale","=","RAISON 2"],"or",["exposant.raisonSociale","=","EXP2"]],"and",[["etat","=","Affecté"],"or",["etat","=","En Cours"]]];
Code:exposant.raisonSociale,=,Paul Est Le Meilleur|and|etat,=,Affecté,or,etat,=,Nouveau
Bizarrement cela fait pareil ....
Code:sqlWHERE => exposant.raisonSociale=Paul Est Le Meilleurorexposant.raisonSociale=Alexandre
Montre ton objet filter (PAS JSON.parse(filter) ! )
Montre un copier-coller de la console.Code:
1
2
3
4 console.log ( JSON.stringify( filter ) ); // converti en chaine var sqlWHERE = get_filter_sqlwhere( filter ); console.log ( sqlWHERE );
Bonjour,
Le filter c'est si je le passe avec JSON.parse depuis Angular : j'ai :
[[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Affecté"],"or",["etat","=","Nouveau"]]]
Et le resultat de get_filter_sqlwhere :
sqlWHERE => (((\ exposant.raisonSociale\ \ =\ \ Paul Est Le Meilleur\ )\ or\ (\ exposant.raisonSociale\ \ =\ \ Alexandre\ ))\ and\ ((\ etat\ \ =\ \ Affecté\ )\ or\ (\ etat\ \ =\ \ Nouveau\ )))
Par contre si je passe pas depuis Anguar la chaine avec JSON mais juste le string filter, le filter est :
MerciCode:exposant.raisonSociale,=,Paul Est Le Meilleur,or,exposant.raisonSociale,=,Alexandre,and,etat,=,Nouveau,or,etat,=,Affecté
OK.
C'est sous cette forme qu'il faut soumettre filter :
Code:[[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Affecté"],"or",["etat","=","Nouveau"]]]
La fonction récursive est :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 function get_filter_sqlwhere_recursive( arr, add_where=true ) { var sqlAndOr = ['and','or']; var sqlwhere = '('; if( Array.isArray(arr) ) { arr.forEach( function(elts, index) { if( Array.isArray(elts) ) { if( sqlAndOr.indexOf(elts[1])>-1 ) // and | or { sqlwhere += get_filter_sqlwhere_recursive( elts, false ); // récursivité } else { sqlwhere += elts[0].replace(/([^\. ]+)/gi,'`$1`') + elts[1] + '\''+elts[2]+'\''; } } else { sqlwhere += ') '+elts.toUpperCase()+' ('; // AND | OR } }); } sqlwhere += ')'; if( add_where ){ sqlwhere = ' WHERE '+sqlwhere; } return sqlwhere; }
J'obtiens :Code:
1
2
3
4
5 var filter = [[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Affecté"],"or",["etat","=","Nouveau"]]]; //console.log ( filter ); var sqlWHERE = get_filter_sqlwhere_recursive( filter ); console.log ( 'sqlWHERE : '+ sqlWHERE );
Code:sqlWHERE : WHERE ((`exposant`.`raisonSociale`='Paul Est Le Meilleur') OR (`exposant`.`raisonSociale`='Alexandre')) AND ((`etat`='Affecté') OR (`etat`='Nouveau'))
Bonjour,
etrange : j'ai bien cela en filter :
et j'ai le retour : sqlWHERE => WHERE ()Code:[[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Nouveau"],"or",["etat","=","Affecté"]]]
Encore merci
Bon....
Peux-tu nous montrer ce que renvoie :
Ca devrait être : object.Code:console.log ( typeof filter );
Si c'est string, alors ce n'est pas bon.
Il faut faire d'abord :
Exemple :Code:filter = JSON.parse( filter );
Code:
1
2
3
4 var filter = [[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Affecté"],"or",["etat","=","Nouveau"]]]; // PAS de '...' autour : c'est un objet (object) console.log ( 'filter : '+ filter ); console.log ( typeof filter ); // object
N.B. si avec ça, tu ne t'en sors pas,.... je suis a bout d'arguments...Code:
1
2
3
4
5
6
7
8
9 var filter = '[[["exposant.raisonSociale","=","Paul Est Le Meilleur"],"or",["exposant.raisonSociale","=","Alexandre"]],"and",[["etat","=","Affecté"],"or",["etat","=","Nouveau"]]]'; // REMARQUER les '...' autour : c'est une chaine (string) console.log ( 'filter : '+ filter ); console.log ( typeof filter ); // string // on PARSE : on obtient un objet JSON filter = JSON.parse( filter ); console.log ( 'filter : '+ filter ); console.log ( typeof filter ); // object