【问题标题】:How do you chain functions using lodash?你如何使用 lodash 链接函数?
【发布时间】:2016-06-06 01:22:57
【问题描述】:

我有一个看起来像的对象

var foundUser = {
    charData: []
}

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

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

但是我得到了一些我不需要的额外属性(这不能通过 select 解决)

所以我打电话

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

如果我能做到就好了

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

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

【问题讨论】:

标签: javascript lodash


【解决方案1】:

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

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

进一步说明:

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

如果您使用_.chain(...),您将创建一个带有显式方法链接的lodash 对象。结果始终是一个已包装的值,并且始终需要通过调用 .value() 对其进行解包。

为了进一步参考这里是文档的链接:

Explicit chaining in Lodash

Implicit chaining in Lodash

【讨论】:

  • 我想不出你需要它的原因,但如果你想更明确一点,还有`_.chain(foundUser)`。
  • 本来要发表同样的评论,你没有来包装对象
  • @RobM。如果你这样做 _.chain() 你还在包装对象,它只是更明确
【解决方案2】:

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

尝试利用_.flow

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

var foundUser = {
    charData: []
};

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

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

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

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

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

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

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

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

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

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

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

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

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

npm i --save lodash.flow

对比

npm i --save lodash

在许多实际应用程序中,这可能是一个微不足道的优势,在这些应用程序中,拥有完整的 Lodash 构建不是问题,并且可以说更容易保持最新状态,但如果您正在编写将要分发的库或脚本,则非常方便用作第三方工具。在这种情况下,就分布式大小而言,您将能够保持您的足迹更小。

Lodash 方法文档:

值得一看的文章:

还有几点需要注意:

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

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

例子:

_.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);

【讨论】:

  • 从你的例子中得到一个函数错误@Nobita
  • @BabluAhmed 确保您导入的是 FP 版本的 Lodash (import _ from 'lodash/fp 而不是“标准”版本 (import _ from 'lodash')
  • 然后@Nobita,在这里提到相应的代码版本
  • @BabluAhmed 它就在“使用 Lodash FP 我们可以通过...”的解释中,并且有一个指向 repo 的链接。如果您觉得应该用不同的措辞随意编辑,我们毕竟是这样的:)。干杯。
【解决方案3】:

你试过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)

【讨论】:

  • 我正在考虑使用lodash/fp,因为我有使用Ramda 的经验,但有一个缺点......文档真的很差(加上打字稿中没有方法cmets),并且在建立 AFAIK
  • 是的。文档很糟糕。但是您可以阅读lodash 的文档并颠倒参数的顺序。工作 95% 的时间。 :) 对于摇树,我使用github.com/lodash/babel-plugin-lodash
  • 我们不使用 babel,但否则那将是一个不错的选择 ?
【解决方案4】:

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

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

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

_.chain(foundUser)
 .assignIn(rows[0])
 .tap(console.log)
 .omit(['blah'])
 .value()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    相关资源
    最近更新 更多