如何将2个点表示法字符串合并到GraphQL查询字符串中

时间:2017-12-07 22:36:21

标签: javascript graphql graphql-js

我尝试将2个点符号字符串合并到只有javascript的GrahQL查询中(可以是ES6 / typescript)。

例如,假设我有一个字符串数组

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

预期的查询字符串输出将是(空格不重要)

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

我可以将点符号1逐1转换为查询字符串,但如何将所有这些合并在一起呢?我得到了一个带street.name和输出street { name }的函数。所以这个功能会这样做

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 }

但是接下来我将如何循环遍历所有字符串并仅获得1个将相同属性组合到一个组中的GraphQL查询字符串。主要问题是如何合并2点符号字符串而不丢失任何内容并且没有重复项(此时,我可以获得此address { name } address { zip }但是当它在GraphQL服务器上运行时,只保留后者,因此只有zip出现在结果中。

我尝试创建代表结构的临时对象,但这样做并没有那么好。

1 个答案:

答案 0 :(得分:1)

修订答案

根据您修改后的问题和要求,这是修改后的答案。这将从嵌套点符号递归构建一个对象,然后利用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);

原始答案

我建议先将单个点符号字符串转换为对象,然后将对象转换为字符串。

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 }"