我该如何安排这些功能的高阶

时间:2018-07-10 16:31:17

标签: javascript functional-programming

而不是具有以下两个字符串函数并同时调用它们

removeTrailingSlash = (site) => site.replace(/\/$/, "");

getLastPartOfURL = (url) => url.substr(url.lastIndexOf('/') + 1);

我希望能够将它们组合成一个高阶函数定义

removeTrailingSlash = (site) => site.replace(/\/$/, "");

getLastPartOfURL = site => removeTrailingSlash => url => url.substr(url.lastIndexOf('/') + 1);

所以我想我不清楚如何使用箭头功能来执行此操作,或者是否有更优雅的方法。谢谢。

5 个答案:

答案 0 :(得分:1)

高阶函数是将函数作为参数和/或返回函数的函数。

此答案假设您想更多地了解高阶函数(因此标题),而不仅仅是在寻找一种更好的方法来获取路径的最后一部分(因为这可能并非如此)。

在第二个示例中:

getLastPartOfURL = site => removeTrailingSlash => url => url.substr(url.lastIndexOf('/') + 1);

我读到getLastPartOfURL将是一个接受参数site的函数,并返回一个接受参数removeTrailingSlash的函数,该参数返回一个接受参数url的函数,并且然后返回该网址的子字符串。请注意,您传入这些函数的大多数参数(siteremoveTrailingSlash)并未使用。

对于这样的安排,您可以将实际函数传递给这些参数,然后在最后组合函数以获得最终结果。

例如:

//define a few simple functions
const removeTrailingSlash = (url) => url.replace(/\/$/, "");
const getLast = (url) => url.substr(url.lastIndexOf('/') +1 )

// define a higher order function that expects functions as arguments and composes them
const getLastPartOfURL = removeTrailingSlashFN => getLastFN => url => getLastFN(removeTrailingSlash(url))

// call it by passing in functions and url:

let result = getLastPartOfURL(removeTrailingSlash)(getLast)("http://www.example.com/test/")
console.log(result)

/* Notice that this arrangement allows you to make function partials! */

let partial = getLastPartOfURL(removeTrailingSlash)(getLast)
// now you only need to pass in url
console.log(partial("http://www.example.com/foo/"))
console.log(partial("http://www.example.com/bar/"))

还有许多其他模式,但是希望这会有所帮助。

答案 1 :(得分:1)

您已经对高阶函数有了一个不错的答案,但是我认为您可能真正需要的概念是函数组成。合成使您可以定义一个新函数,该函数是将一个函数的结果传递到另一个函数的输入中的结果,例如:

const compose = (f, g) => x => f(g(x));

// Your original functions
const removeTrailingSlash = url => url.replace(/\/$/, "");
const getLast             = url => url.substr(url.lastIndexOf('/') + 1);

const both = compose(getLast, removeTrailingSlash);

console.log(both('http://www.example.com/foo/'));
console.log(both('http://www.example.com/bar/'));

// You can even do another composition for logging
const logBoth = compose(console.log, both);
logBoth('http://www.example.com/foo/');
logBoth('http://www.example.com/bar/');

请注意,在这种特殊情况下,实际上compose是高阶函数。它以两个函数fg作为参数,并返回一个新函数。新的组合函数both本身并不被认为是高阶函数,即使它是使用一个函数创建的。它以字符串作为参数并返回一个字符串。

还请注意,尽管您可以像上面一样定义自己的构图,但将其作为already included到Ramda之类的库中已经足够了。

答案 2 :(得分:0)

我假设您期望从类似bar的输入中获得https://google.com/foo/bar/的输出。

如果是这种情况,那么我建议像这样。

url.split('/').filter(Boolean).pop();

这会根据斜杠的位置将您的网址拆分为一个数组(在本示例中为['https:', '', 'google.com', 'foo', 'bar', '']),然后它将过滤掉所有空字符串,然后返回最后一项(bar

如果您真的希望它们具有不同的功能,那么我建议您使用类似Method chaining的方法,这样您就可以执行以下操作:

答案 3 :(得分:0)

我猜您需要一个函数来获取以/结尾的url的最后一部分。

const getLastPart = url => url.match(/\/(\w*)\/$/)[1];

const p = getLastPart('part1/part2/part3/');
console.log(p);

答案 4 :(得分:0)

我怀疑 1 您只是想让getLastPartOfURL在返回之前呼叫removeTrailingSlash

const removeTrailingSlash = (url) => url.replace(/\/$/, '');
const getLastPartOfURL = (url) => {
    const noTrailing = removeTrailingSlash(url);    // call removeTrailingSlash
    return noTrailing.substr(noTrailing.lastIndexOf('/') + 1);
};

const tests = [
  'http://www.example.com',
  'www.example.com/foo',
  'http://www.example.com/foo/bar',
  'http://www.example.com/foo/bar/',
  'www.example.com/foo/index.html',
];

console.log(JSON.stringify(tests.map(getLastPartOfURL)));

1:Higher-Order Function是一个将函数作为参数或返回函数作为其输出的函数。