【问题标题】:Getting a string from a range of possible paths从一系列可能的路径中获取字符串
【发布时间】:2018-03-19 01:29:56
【问题描述】:

我有一个场景,我需要从一个对象中获取第一次出现的字符串,但前提是匹配发生在一个预定义的路径中。

{ 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

如果一位经验丰富的函数式程序员能为我提供一些替代的实现方法,我将不胜感激。谢谢。

【问题讨论】:

  • 既然你有工作代码,并且真的要求审查,这个问题更适合CodeReview
  • 由于您的更新,我删除了我的答案。但我同意上面的评论。您有使用要使用的框架的工作代码。听起来像是代码审查。
  • 是的,我同意你们的看法。感谢您的时间和 cmets。 The question has been moved

标签: javascript node.js string functional-programming ramda.js


【解决方案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 将复杂的 isString 替换为 R.is(String)。柯里化可以让你提供前两个参数来创建更有用的函数。

您可以在 Ramda REPL 中看到这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    相关资源
    最近更新 更多