Javascript 你如何使用 lodash 链接函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35590543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 17:56:23  来源:igfitidea点击:

How do you chain functions using lodash?

javascriptlodash

提问by Datsik

I have an object that looks like

我有一个看起来像的对象

var foundUser = {
    charData: []
}

which then I load an object from a database using mysql and then I call

然后我使用 mysql 从数据库加载一个对象,然后我调用

_.assignIn(foundUser, rows[0]);

But I get a few extra properties that I don't need (this isn't solvable by using select)

但是我得到了一些我不需要的额外属性(使用 select 无法解决这个问题)

So I call

所以我打电话

foundUser = _.omit(foundUser, ['blah']);

But it would be nice if I could just do

但如果我能做到就好了

_.assignIn(foundUser, rows[0]).omit(rows[0], ['blah']);

But that throws an error, am I doing it wrong or is there another way this can be done?

但这会引发错误,是我做错了还是有其他方法可以做到?

回答by Kenneth

To chain with lodash, you first have to wrap the object:

要使用 lodash 链接,首先必须包装对象:

_(foundUser).assignIn(rows[0]).omit(['blah']).value();

Further clarification:

进一步澄清:

The _creates a lodash object which allows for implicit method chaining. Implicit method chaining means that in certain circumstances it may return a primitive value, in others it may return a lodash object that you need to unwrap by calling .value()on it.

_创建一个对象lodash其允许隐式方法链接。隐式方法链意味着在某些情况下它可能返回一个原始值,在其他情况下它可能返回一个 lodash 对象,您需要通过调用.value()它来解包。

If you'd use _.chain(...), you'd be creating a lodash object with explicit method chaining. The result is always a wrapped value and always needs to be unwrapped by calling .value()on it.

如果您使用_.chain(...),您将创建一个带有显式方法链的 lodash 对象。结果总是一个包装的值,总是需要通过调用.value()它来解包。

For further reference here are the links to the documentation:

如需进一步参考,请访问文档链接:

Explicit chaining in Lodash

Lodash 中的显式链接

Implicit chaining in Lodash

Lodash 中的隐式链接

回答by Nobita

As an alternative to the wrap-chain-unwrap pattern (nothing inherently wrong with it, but alternatives are always interesting) there's another way you can check.

作为 wrap-chain-unwrap 模式的替代方案(它本身没有什么问题,但替代方案总是很有趣)还有另一种方法可以检查。

Try by leveraging _.flow.

尝试利用_.flow.

The idea is that every function inside flowwill receive as input the output of the previous one, which is exactly what you need. An example, given this data:

这个想法是内部的每个函数flow都将接收前一个函数的输出作为输入,这正是您所需要的。一个例子,给定这个数据:

var foundUser = {
    charData: []
};

var rows = [{ok: 1, blah: 'nope'}];

Using Lodash FPwe can pass the data as last argument. This feature along with the auto-currying of each method in Lodash/fp makes our life easier when composing functions. This means we can have this succinct and expressive code:

使用Lodash FP我们可以将数据作为最后一个参数传递。这个特性以及 Lodash/fp 中每个方法的自动柯里化让我们在组合函数时更轻松。这意味着我们可以拥有这个简洁而富有表现力的代码:

_.flow(
 _.assign(rows[0]),
 _.omit('blah')
)(foundUser);

// >> {"charData":[],"ok": 1}

Using the standard version of Lodash we have to curry those functions ourselves using _.partial, and the code will certainly look less terse, but it is still possible to do so:

使用标准版的 Lodash,我们必须自己使用 curry 这些函数_.partial,代码看起来肯定不那么简洁,但仍然可以这样做:

_.flow(
 _.partialRight(_.assign, rows[0]),
 _.partialRight(_.omit, 'blah')
)(foundUser);

// >> {"charData":[],"ok": 1}

A great benefit of using flow rather than chaining is that you can easily mix Lodash methods with your own custom functions, since - as said - all they need is just data as input and data as output, and nothing else:

使用流而不是链接的一大好处是,您可以轻松地将 Lodash 方法与您自己的自定义函数混合使用,因为 -如上所述- 它们所需要的只是数据作为输入和数据作为输出,除此之外别无他物:

const yourFunction = d => ({ ...d, yourProp: 4 });

_.flow(
 _.assign(rows[0]),
 yourFunction,
 _.omit('blah')
)(foundUser);

// >> {"charData":[],"ok": 1, yourProp: 4}

This makes function composition much easier and more flexible and arguably will naturally lead to more expressive code.

这使得函数组合更容易、更灵活,并且可以说自然会导致更具表现力的代码。

Another thing to note. If you are installing and importing only the Lodash methods you use, you will have to add just the flowpackage and not the whole Lodash library as you'd do with chaining.

还有一点要注意。如果您只安装和导入您使用的 Lodash 方法,您将只需要添加flow包,而不是像链接那样添加整个 Lodash 库。

npm i --save lodash.flow

Vs

对比

npm i --save lodash

Perhaps a negligible advantage in many real-world applications where having the full build of Lodash is not a problem and arguably easier to maintain up to date, but very handy in case you are writing a library or a script that will be distributed to use as a third party tool. In that case you will be able to keep your footprint way lower in terms of distributed size.

在许多实际应用程序中,拥有 Lodash 的完整构建不是问题并且可以说更容易维护更新,这可能是一个可以忽略不计的优势,但是如果您正在编写一个库或脚本将被分发用作第三方工具。在这种情况下,您将能够在分布式大小方面保持较低的足迹。

Lodash methods docs:

Lodash 方法文档:

Two articles worth checking out:

值得一看的两篇文章:

NB - the title of the second article is a bit harsh in my opinion but don't skip it, the content is indeed very informative.

NB - 第二篇文章的标题在我看来有点苛刻,但不要跳过它,内容确实非常有用。

A few other things to note:

其他一些注意事项:

  • In Lodash/fp Flow is aliased as _.pipe, so you can pick whichever you prefer.

  • You can also use _.flowRight(or its fpalias _.compose) if you prefer right to left composition, as seen in Ramda's compose.

  • 在 Lodash/fp Flow 中的别名为_.pipe,所以你可以选择你喜欢的任何一个。

  • 如果您更喜欢从右到左的合成,也可以使用_.flowRight(或其fp别名_.compose),如Ramda 的 compose 所示

Example:

例子:

_.flow(
 _.assign(rows[0]), // #1st to execute
 yourFunction,  // #2
 _.omit('blah'),  // #3
)(foundUser);

// is the same as...

_.flowRight(
 _.omit('blah'), // #3rd to execute
 yourFunction, // #2
 _.assign(rows[0]), // #1
)(foundUser);

回答by Daniel

Have you ever tried lodash/fp? It comes with all the same functions, but they are curried and none of them mutates the input.

你有没有试过lodash/fp?它具有所有相同的功能,但它们是柯里化的,并且它们都不会改变输入。

Because of that, you can compose them in a really nice way.

因此,您可以以非常好的方式组合它们。

Example:

例子:

import moment from 'moment'
import { compose, filter, groupBy, size, sortBy } from 'lodash/fp'

const fromAdmin = filter({ type: 'admin' })
const groupedByDate = groupBy(message => moment(message.createdAt).format('YYYYMMDD'))
const sorted = sortBy('createdAt')
const unreadByUser = filter({ isReadByUser: false })

const groupedMessages = compose(
  groupedByDate,
  sorted,
  unreadByUser,
  fromAdmin,
)(messages)