简体   繁体   English

如何将2个点符号字符串合并到GraphQL查询字符串

[英]How can I merge 2 dot notation strings to a GraphQL query string

I'm trying to merge 2 dot notation strings into a GrahQL query with only javascript (it can be ES6/typescript). 我正在尝试将2个点符号字符串合并到仅使用javascript的GrahQL查询中(可以是ES6 /打字稿)。

For example, let say that I have an array of strings 例如,假设我有一个字符串数组

[
    'firstName', 
    'lastName', 
    'billing.address.street', 
    'billing.address.zip', 
    'shipping.address.street', 
    'shipping.address.zip'
]

The expected query string output would be (white spaces are not important) 预期的查询字符串输出为(空格不重要)

firstName, lastName, shipping{address{street, zip}}, billing{address{street, zip }}

I can convert 1 by 1 the dot notation to a query string, but how do I merge all of that together? 我可以将点表示法乘以1转换为查询字符串,但是如何将所有这些合并在一起? I got a function that take street.name and output street { name } . 我有一个函数,它接受street.name并输出street { name } So this function would do it 所以这个功能可以做到

convertToString(inputString) {
    let result = '';

    if (inputString.indexOf('.') === -1) {
      result = inputString;
    } else {
      const inputArray = inputString.split('.');
      for (let i = inputArray.length - 1; i >= 0; i--) {
        if (i === 0) {
          result = inputArray[i] + result;
        } else {
          result = '{' + inputArray[i] + result + '}';
        }
      }
    }
    return result;
}

console.log(convertToString('address.street')); // address { street }

But then how would I loop through all strings and get only 1 GraphQL query string that combines the same properties into a group. 但是,然后我将如何遍历所有字符串并仅获得1个将相同属性组合到一个组中的GraphQL查询字符串。 The main issue is how do I merge the 2 dot notation strings without losing anything and without having duplicates (at this point, I can get this address { name } address { zip } but when this runs on the GraphQL server, only the latter is kept and so only the zip shows up in the result. 主要问题是如何合并2个点表示法字符串而不丢失任何内容且没有重复项(此时,我可以获取此address { name } address { zip }但是当它在GraphQL服务器上运行时,只有后者保留,因此结果中仅显示zip

I tried creating temporary object that represent the structure, but that didn't work out so good. 我尝试创建表示该结构的临时对象,但是效果并不理想。

Revised Answer 修改后的答案

Based on your revised question and requirements, here's a revised answer. 根据您修改后的问题和要求,这是修改后的答案。 This will recursively build an object from nested dot notations, and then leverage JSON.stringify to build the query string (with some string manipulations); 这将从嵌套的点表示法递归地构建一个对象,然后利用JSON.stringify来构建查询字符串(通过一些字符串操作);

 function buildQuery(...args) { const set = (o = {}, a) => { const k = a.shift(); o[k] = a.length ? set(o[k], a) : null; return o; } const o = args.reduce((o, a) => set(o, a.split('.')), {}); return JSON.stringify(o) .replace(/\\"|\\:|null/g, '') .replace(/^\\{/, '') .replace(/\\}$/, ''); } const query = buildQuery( 'firstName', 'lastName', 'billing.address.street', 'billing.address.zip', 'shipping.address.street', 'shipping.address.zip' ); console.log(query); 

Original Answer 原始答案

I would suggest converting the individual dot notation strings into an object first, and then converting the object to a string. 我建议先将各个点符号字符串转换为对象,然后再将该对象转换为字符串。

function buildQuery(...args) {
    let q = {};

    args.forEach((arg) => {
        const [ o, a ] = arg.split('.');
        q[o] = q[o] || [];
        if (a) q[o] = q[o].concat(a);
    });

    return Object.keys(q).map((k) => {
        return q[k].length ? `${k} \{ ${q[k].join(', ')} \}` : k;
    }).join(', ');
}

const query = buildQuery('person.name', 'person.email', 'street.name', 'street.zip');
console.log(query);
// "person { name, email }, street { name, zip }"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM