1

나는 사전 정의 된 경로 중 하나에서 일치가 발생하는 경우에만 개체에서 문자열의 첫 번째 항목을 가져와야하는 시나리오가 있습니다. 위의 두 개체 중 하나를 제공하는 경우가능한 경로 범위에서 문자열 가져 오기

{ id: 'I60ODI', description: 'some random description' } 
{ foo: 'bar', description: { color: 'green', text: 'some description within text' } } 

, 나는이 솔루션은 some random description 또는 some description within text 중 하나가, 두 개의 가능한 경로가 obj.descriptionobj.description.text을 것을 제공 복귀 기대. 나중에 새 경로를 추가해야 할 수도 있으므로 추가하기가 쉽습니다.

여기는 지금까지 구현 한 솔루션이지만 나에게는 최적이 아닌 것으로 보입니다.

// require the ramda library 
const R = require('ramda'); 

// is the provided value a string? 
const isString = R.ifElse(R.compose(R.equals('string'), (val) => typeof val), R.identity, R.always(false)); 
const addStringCheck = t => R.compose(isString, t); 

// the possible paths to take (subject to scale) 
const possiblePaths = [ 
    R.path(['description']), 
    R.path(['description', 'text']) 
]; 
// add the string check to each of the potential paths 
const mappedPaths = R.map((x) => addStringCheck(x), possiblePaths); 

// select the first occurrence of a string 
const extractString = R.either(...mappedPaths); 

// two test objects 
const firstObject = { description: 'some random description' }; 
const secondObject = { description: { text: 'some description within text' } }; 
const thirdObject = { foo: 'bar' }; 

console.log(extractString(firstObject)); // 'some random description' 
console.log(extractString(secondObject)); // 'some description within text' 
console.log(extractString(thirdObject)); // false 

노련한 기능적 프로그래머가 구현 방법에 대한 대안을 제공한다면 정말 감사하겠습니다. 감사.

+0

코드를 작성 했으므로 검토를 요청하기 때문에이 질문은 [CodeReview] (https://codereview.stackexchange.com/)에 더 적합합니다. – trincot

+0

업데이트로 내 대답을 삭제했습니다. 그러나 위의 의견에 동의합니다. 사용할 프레임 워크를 사용하여 작업 코드가 있습니다. 코드 검토와 같은 것 같습니다. – user2263572

+0

네, 나는 너희들에 동의한다. 시간과 의견에 감사드립니다. [질문이 이동되었습니다] (https://codereview.stackexchange.com/q/177392/150458) – user2627546

답변

1

이 작동합니다, 나는 그것을 청소기 생각 :

const extract = curry((defaultVal, paths, obj) => pipe( 
    find(pipe(path(__, obj), is(String))), 
    ifElse(is(Array), path(__, obj), always(defaultVal)) 
)(paths)) 

const paths = [['description'], ['description', 'text']] 

extract(false, paths, firstObject) //=> "some random description" 
extract(false, paths, secondObject) //=> "some description within text" 
extract(false, paths, thirdObject) //=> false 

내가 개인적으로 false보다 ''에서 더 나은 기본을 찾을 것입니다,하지만 그건 당신의 전화입니다.

이렇게하면 모든 경로를 통해 매핑되지 않으며 첫 번째 경로가 발견되면 중지됩니다. 또한 Ramda의 is을 사용하여 컴플렉스 isStringR.is(String)으로 바꿉니다. 그리고 currying을 사용하면 더 유용한 함수를 만들기 위해 첫 번째 또는 두 개의 매개 변수를 제공 할 수 있습니다.

Ramda REPL에서 확인할 수 있습니다.

관련 문제