javascript - Ramda:如何通过柯里化、过滤和映射来最小化计算资源?
问题描述
我正在使用 Ramda 构建一个 React 应用程序。我还是函数式编程的新手(大约两个月)。
我有一个这样的联系人列表:
const contacts = [
{
id: 1,
firstName: 'Sven',
lastName: 'Hillstedt',
city: 'Aachen',
company: '',
position: 'Student',
group: 'friends',
tendency: 'maintain'
},
{
id: 2,
firstName: 'David',
// ...
];
给定一个字符串,我需要过滤这个(很长,10.000-100.000)列表。但我只需要考虑键firstName
, lastName
,city
和. 有一个包含这些的数组:company
position
const FIRST_NAME = 'firstName';
const LAST_NAME = 'lastName';
const CITY = 'city';
const COMPANY = 'company';
const POSITION = 'position';
export const stringFields = [FIRST_NAME, LAST_NAME, CITY, COMPANY, POSITION];
现在,我使用 Ramda 编写了以下函数,它接受一个string
和一个联系人列表,映射联系人的键,选择相关的键并将它们小写,然后返回过滤后的联系人:
import { any, filter, includes, map, pick, pipe, toLower, values } from 'ramda';
const contactIncludesValue = value =>
pipe(
pick(stringFields),
map(toLower),
values,
any(includes(value))
);
const filterContactsByValue = value => filter(contactIncludesValue(value));
正如您所看到的,这段代码很混乱(甚至认为它比命令式执行要漂亮得多)。我咖喱value =>
很多次,感觉不太理想。我也在质疑,这段代码是否只对联系人进行一次迭代,以及它是否有效。
您将如何过滤和映射(仅选择相关键 + lowerCase
)大量联系人而不对其进行两次或更多次迭代?有没有办法避免我的柯里化并写出这个更清洁的东西?
解决方案
这里有几件事需要回应。
即使评论有点刻薄,@zerkms 也是对的。除非您知道代码实际上性能不佳,否则尝试性能优化几乎没有意义,特别是如果它使代码更难编写或维护。
你不会
value =>
多次咖喱。它只在前面进行了咖喱,并且每次过滤列表都会发生一次您的值的部分应用。您只迭代一次您的联系人。但在每一个内部都是
any
对您的字段列表的调用。如果找到匹配项,它会提前返回,因此计算调用次数并非易事,但它可能是字段数和联系人数O(m * n)
在哪里。m
n
这个版本的代码稍微更简洁。您可能会或可能不会发现它更具可读性:
const contactIncludesValue = value =>
pipe(
props(stringFields),
map(toLower),
any(includes(value))
);
const filterContactsByValue = pipe(contactIncludesValue, filter);
请注意,这props
比 更方便pick(...) -> values
,并且中间的map(toLower)
工作也一样好。
推荐阅读
- spring - 如何查询具有空值的文档 MongoRepository Spring Data MongoDB
- highcharts - 带有日期时间折线图的 Highcharts 自定义属性
- python - Django 迁移未应用于连接的数据库
- vb.net - Vb.net - 读取 http 侦听器的输入流时流读取器引发错误
- javascript - 如何在另一个网页中打开网页而不向外界透露
- android - 如何在 android oreo 的锁定屏幕上显示音乐播放器之类的通知?
- coffeescript - Coffeescript 将数组转换为字典,其中字典将具有多个值
- javascript - 在父级 HTML 字符串之间的特定点附加 DOM 元素
- deep-learning - Darkflow 已完美安装和导入。但是 TFNet 不是从 darkflow.net.build 导入的
- mongodb - 已解决:如何创建没有卷的 Mongodb docker 容器