2017-12-07 9 views
0

2 점 표기법 문자열을 GrahQL 쿼리에만 병합하려고합니다 (ES6/typescript 일 수 있음). 예를 들어2 도트 표기법 문자열을 GraphQL 쿼리 문자열에 병합하는 방법

(공백은 중요하지 않습니다)

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

내가 일을 변환 할 수 있습니다 내가 예상 쿼리 문자열 출력이 될 것

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

문자열 배열을 가지고 있다고 가정 해 봅시다 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

수정 된 질문 및 요구 바탕으로 개정 대답

을, 여기에 개정 된 답변.이 기능은 중첩 된 도트 표기법을 사용하여 반복적으로 객체를 작성한 다음 레버를 사용합니다. e 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 }" 
+0

내 질문을 업데이트 한 후 정말 찾고있는 솔루션을 닫습니다. (방금 본 적이 없으므로). 질문에 제공된 인수 목록으로 buildQuery를 실행하면 응답에 일반 문자열'lastName {}, 청구서 수신 주소 {address, address}'에 중괄호가 추가되어'lastName'에 {{ }' – ghiscoding

+0

답변을 업데이트했습니다. 코드를 조금 개선 할 수도 있지만 작동하는 것 같습니다. – fubar

+1

jsbin을 시도해 보면 argsforEach에 오류가 발생합니다. args'(... args)에 spread 연산자를 추가하면 사라집니다. 답변을 업데이트 하시겠습니까? – ghiscoding