如何在Typescript中创建一个将动态JSON转换为公式的函数

yuvru6vn  于 2023-10-22  发布在  TypeScript
关注(0)|答案(1)|浏览(131)

我需要创建一个方法来转换具有以下结构的动态JSON

  1. export interface Regole {
  2. descrizioneRegola: string;
  3. naturaGiuridica: string;
  4. regolaPerCollegamento: RegolaPerCollegamento[];
  5. or?: OperatoreLogico;
  6. and?: OperatoreLogico;
  7. not?: OperatoreLogico;
  8. }
  9. export interface OperatoreLogico {
  10. regolaPerCollegamento?: RegolaPerCollegamento[];
  11. or?: OperatoreLogico;
  12. and?: OperatoreLogico;
  13. not?: OperatoreLogico;
  14. }
  15. export interface RegolaPerCollegamento {
  16. tipoCollegamentoEsistente?: number;
  17. tipoCollegamento?: number;
  18. quantita?: string;
  19. minimo?: number;
  20. massimo?: number;
  21. esattamente?: number;
  22. }

其中键**“或”,“和”,“不是”**可以是动态的。
例如,我可以在输入中输入这个Json

  1. let json: OperatoreLogico = {
  2. "or": {
  3. "and": {
  4. "regolaPerCollegamento": [
  5. {
  6. "tipoCollegamentoEsistente": 115,
  7. "quantita": "NESSUNO"
  8. },
  9. {
  10. "tipoCollegamentoEsistente": 118,
  11. "quantita": "NESSUNO"
  12. }
  13. ]
  14. },
  15. "or": {
  16. "regolaPerCollegamento": [
  17. {
  18. "tipoCollegamento": 115,
  19. "minimo": 1
  20. },
  21. {
  22. "tipoCollegamento": 118,
  23. "minimo": 1
  24. }
  25. ]
  26. }
  27. }
  28. }

并转换为以下输出:

  1. ({tipoCollegamentoEsistente: 115, quantita: "NESSUNO"} && {tipoCollegamentoEsistente: 118, quantita: "NESSUNO"}) || ({tipoCollegamento: 115, minimo: 1} || {tipoCollegamento: 115, minimo: 1})

正如你所看到的,在上面的例子中,“和”运算符需要对数组中的两个对象执行“和”“,内部的**”或"“是数组中的两个对象,外部的”或“"是连接内部的”和"“或”**“的结果。
我尝试创建一个递归方法,但似乎不起作用

  1. export function convertToRule(operatoreLogico: OperatoreLogico, initial?: OperatoreLogico, operator?: string, result?: string): string {
  2. const initialJson = { ...operatoreLogico };
  3. if (operatoreLogico.regolaPerCollegamento) {
  4. const regole = Array.isArray(operatoreLogico.regolaPerCollegamento)
  5. ? operatoreLogico.regolaPerCollegamento
  6. : [operatoreLogico.regolaPerCollegamento];
  7. const regoleString = regole.map((regola: any) => {
  8. const properties = Object.keys(regola).map((key) => {
  9. return `"${key}": ${JSON.stringify(regola[key])}`;
  10. }).join(', ');
  11. return `{ ${properties} }`;
  12. }).join(operator);
  13. let op = Object.keys(initial!)[0];
  14. if (op === 'and') {
  15. delete initial?.and;
  16. result = '(' + result + ' && ' + regoleString+ ')';
  17. convertToRule(initial!, undefined, undefined, result + regoleString);
  18. } else {
  19. delete initial?.or;
  20. result = '(' + result + ' || ' + regoleString + ')';
  21. convertToRule(initial!, undefined, undefined, result + regoleString);
  22. }
  23. return `( ${regoleString} )`;
  24. } else if (operatoreLogico.and) {
  25. const andRules = Array.isArray(operatoreLogico.and) ? operatoreLogico.and : [operatoreLogico.and];
  26. andRules.map((andRule) => {
  27. return convertToRule(andRule, initialJson, ' && ', result);
  28. })
  29. return '';
  30. } else if (operatoreLogico.or) {
  31. const orRules = Array.isArray(operatoreLogico.or) ? operatoreLogico.or : [operatoreLogico.or];
  32. orRules.map((orRule) => {
  33. return convertToRule(orRule, initialJson, ' || ', result);
  34. })
  35. return '';
  36. } else {
  37. return '';
  38. }
  39. }
pdsfdshx

pdsfdshx1#

这应该是你想要的:

  1. function compile(obj, op) {
  2. if (obj.regolaPerCollegamento)
  3. return obj.regolaPerCollegamento.map(p => JSON.stringify(p)).join(op)
  4. let res = []
  5. for (let [op, val] of Object.entries(obj)) {
  6. if (op === 'and')
  7. res.push(compile(val, ' && '))
  8. if (op === 'or')
  9. res.push(compile(val, ' || '))
  10. if (op === 'not')
  11. res.push('not ' + compile(val, ' '))
  12. }
  13. if (res.length === 1)
  14. return res[0]
  15. return '(' + res.join(op) + ')'
  16. }
  17. //
  18. let json = {
  19. "or": {
  20. "and": {
  21. "regolaPerCollegamento": [
  22. {
  23. "tipoCollegamentoEsistente": 115,
  24. "quantita": "NESSUNO"
  25. },
  26. {
  27. "tipoCollegamentoEsistente": 118,
  28. "quantita": "NESSUNO"
  29. }
  30. ]
  31. },
  32. "or": {
  33. "regolaPerCollegamento": [
  34. {
  35. "tipoCollegamento": 115,
  36. "minimo": 1
  37. },
  38. {
  39. "tipoCollegamento": 118,
  40. "minimo": 1
  41. }
  42. ]
  43. }
  44. }
  45. }
  46. b = compile(json, ' ')
  47. console.log(b)

也就是说,这是一种奇怪的表示AST的方式,你可能会更好地使用这样的结构:

  1. interface Rule {
  2. whatever
  3. }
  4. interface Node
  5. {
  6. op: string
  7. args: Array <Node | Rule>
  8. }
  9. //
  10. let ast = {
  11. op: 'or',
  12. args: [
  13. {
  14. op: 'and',
  15. args: [
  16. { "tipoCollegamentoEsistente": 115, "quantita": "NESSUNO" },
  17. { "tipoCollegamentoEsistente": 118, "quantita": "NESSUNO" }
  18. ]
  19. },
  20. {
  21. op: 'or',
  22. args: [
  23. { "tipoCollegamento": 115, "minimo": 1 },
  24. { "tipoCollegamento": 118, "minimo": 1 }
  25. ]
  26. }
  27. ]
  28. }
展开查看全部

相关问题