1

私は、オブジェクトから文字列の最初のオカレンスを取得する必要があるシナリオを持っていますが、あらかじめ定義されたパスの1つで一致が発生した場合に限ります。上記二つのオブジェクトのいずれかを提供される場合可能なパスの範囲から文字列を取得する

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

、I溶液は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よりも''でより良いデフォルトを見つけるだろうが、それはあなたの呼び出しです。

これにより、すべてのパスのマッピングが回避され、最初のパスが見つかると停止します。また、ラムダのisを使用して、複合体isStringR.is(String)に置き換えます。また、カリングでは、最初または最初の2つのパラメータを指定して、より便利な関数を作成することができます。

Ramda REPLでこれを確認できます。

関連する問題