你如何使用lodash链接函数?

Dat*_*sik 47 javascript lodash

我有一个看起来像的对象

var foundUser = {
    charData: []
}
Run Code Online (Sandbox Code Playgroud)

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

_.assignIn(foundUser, rows[0]);
Run Code Online (Sandbox Code Playgroud)

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

所以我打电话

foundUser = _.omit(foundUser, ['blah']);
Run Code Online (Sandbox Code Playgroud)

但如果我能这样做会很好

_.assignIn(foundUser, rows[0]).omit(rows[0], ['blah']);
Run Code Online (Sandbox Code Playgroud)

但是这会引发错误,我做错了还是有另外一种方法可以做到这一点?

Ken*_*eth 72

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

_(foundUser).assignIn(rows[0]).omit(['blah']).value();
Run Code Online (Sandbox Code Playgroud)

进一步澄清:

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

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

以下是文档的链接以供进一步参考:

Lodash中的显式链接

Lodash隐含链接

  • 并不是说我能想到你需要它的原因,但如果你想更加明确它,还有`_.chain(foundUser)`. (2认同)
  • @RobM。如果你执行`_.chain()`,你仍然包装对象,它只是更明确 (2认同)

Nob*_*ita 25

作为wrap-chain-unwrap模式的替代方案(没有任何内在错误,但替代方案总是很有趣),还有另一种方法可以检查.

尝试利用_.flow.

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

var foundUser = {
    charData: []
};

var rows = [{ok: 1, blah: 'nope'}];
Run Code Online (Sandbox Code Playgroud)

使用Lodash FP我们可以将数据作为最后一个参数传递.此功能以及Lodash/fp中每种方法的自动调整功能使我们在编写功能时更轻松.这意味着我们可以拥有这个简洁而富有表现力的代码:

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

// >> {"charData":[],"ok": 1}
Run Code Online (Sandbox Code Playgroud)

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

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

// >> {"charData":[],"ok": 1}
Run Code Online (Sandbox Code Playgroud)

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

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

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

// >> {"charData":[],"ok": 1, yourProp: 4}
Run Code Online (Sandbox Code Playgroud)

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

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

npm i --save lodash.flow
Run Code Online (Sandbox Code Playgroud)

VS

npm i --save lodash
Run Code Online (Sandbox Code Playgroud)

在许多真实世界的应用程序中,拥有Lodash的完整版本并不是一个问题并且可以说更容易维护更新,这可能是一个微不足道的优势,但是如果你正在编写一个库或一个将被分发用作的脚本,那么它非常方便第三方工具.在这种情况下,您将能够在分布式大小方面保持较低的足迹.

Lodash方法文档:

两篇值得一试的文章:

NB - 我认为第二篇文章的标题有点苛刻,但不要跳过它,内容确实非常丰富.

其他一些注意事项:

  • 在Lodash/fp Flow中有别名_.pipe,因此您可以选择自己喜欢的.

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

例:

_.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);
Run Code Online (Sandbox Code Playgroud)


Phu*_*hui 8

Chain 是 lodash 中管道的最佳等价物。

_.chain(foundUser)
 .assignIn(rows[0])
 .omit(['blah'])
 .value()
Run Code Online (Sandbox Code Playgroud)

您还可以通过.tap或链接一些自定义函数.thru,例如:

_.chain(foundUser)
 .assignIn(rows[0])
 .tap(console.log)
 .omit(['blah'])
 .value()
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 5

您是否尝试过lodash / fp?它具有所有相同的功能,但是它们都是咖喱状的,而且都没有改变输入。

因此,您可以以一种非常不错的方式编写它们。

例:

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)
Run Code Online (Sandbox Code Playgroud)