2017-10-07 62 views
1

我有一個場景,我需要從對象中抓取第一個字符串,但前提是匹配發生在已經預先定義的某個路徑中。從一系列可能的路徑中獲取字符串

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

當設置或者兩個物體的上面,我期望溶液返回任一some random descriptionsome 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)。而咖喱可以讓你提供第一個或前兩個參數來創建更有用的功能。

您可以在Ramda REPL中看到此操作。

相關問題