Passing _.groupBy to _.partialRight seems to give incorrect results(将_.groupBy传递给_.artialRight似乎给出了不正确的结果)
问题描述
这里有一个JavaScript对象,
const obj = {a: [{ id: 1 }, {id: 1}, {id: 2}, {id: 3}], b: [{ id: 4 }, {id: 5}, {id: 5}, {id: 6}] };
下面的代码按.id
对两个数组ojb.a
和obj.b
中的每个数组中的.id
正确分组,
const res1 = _.map(obj, x => _.groupBy(x, 'id'));
结果为
[
{
1: [{id: 1}, {id: 1}],
2: [{id: 2}],
3: [{id: 3}]
},
{
4: [{id: 4}],
5: [{id: 5}, {id: 5}],
6: [{id: 6}]
}
]
但是,lambda实际上只是对其第二个参数_.groupBy
的部分应用,该参数设置为'id'
,所以我认为这样的操作应该可以,
const res2 = _.map(obj, _.partialRight(_.groupBy, 'id'));
或者至少是这样的
const res2 = _.map(obj, _.partialRight(_.groupBy, x => x.id));
但是,它们都不起作用,都会产生此对象:
[
{
undefined: [{id: 1}, {id: 1}, {id: 2}, {id: 3}]
},
{
undefined: [{id: 4}, {id: 5}, {id: 5}, {id: 6}]
}
]
为什么?它是lodash
中的错误吗?还是因为JavaScript的工作方式?在后一种情况下,发生了什么情况?
我找到了一个现有的question + self-answer,它提供了使上述代码正常工作的解决方案:
const res2 = _.map(obj, _.ary(_.partialRight(_.groupBy, 'id'), 1));
但是,我的部分问题仍然没有得到回答:为什么我需要使用_.ary
?为什么我的初始尝试不起作用?
推荐答案
_.partialRight
方法仍然可以接受比新函数应该接受的参数更多的参数。如果一个函数有两个参数,部分应用了一个或两个,那么任何额外的参数都会有效地将部分应用的参数去掉:
function print(a, b) {
console.log(a, b);
}
const f = _.partialRight(print, "world");
const g = _.partialRight(print, "hello", "world");
f("hi"); // hi world
g(); // hello world
f("hi", "universe"); // hi universe
g("greetings"); // greetings world
g("greetings", "universe"); // greetings universe
<script src="aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9sb2Rhc2hANC4xNy4yMS9sb2Rhc2gubWluLmpz"></script>
发生这种情况是因为_.partialRight
实际上添加到了arguments
对象的末尾:
function print(a, b) {
console.log(...arguments);
}
const f = _.partialRight(print, "world");
const g = _.partialRight(print, "hello", "world");
f("hi"); // hi world
g(); // hello world
f("hi", "universe"); // hi universe world
g("greetings"); // greetings hello world
g("greetings", "universe"); // greetings universe hello world
<script src="aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9sb2Rhc2hANC4xNy4yMS9sb2Rhc2gubWluLmpz"></script>
因此,_.partialRight
构造的函数容易受到the same problem that passing parseInt
as callback has的影响-可以传入更多参数,将传入,因为_.map
的回调总是传递元素、索引和数组。因此,即使_.partialRight(_.groupBy, 'id')
应该将第二个参数设置为'id'
,当_.map
作为callback(item, index, array)
调用函数时,它会变成第四个参数。实际上,执行的回调是
(item, index, array) => _.groupBy(item, index, array, 'id')
这就是使用_.ary(fn, 1)
或直接使用_.unary()
来限制arity的原因-在这种情况下,将丢弃_.map()
中的额外参数,并且只处理第一个参数:
function print(a, b) {
console.log(a, b);
}
const f = _.unary(_.partialRight(print, "world"));
f("hi"); // hi world
f("hi", "universe"); // hi world
<script src="aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9sb2Rhc2hANC4xNy4yMS9sb2Rhc2gubWluLmpz"></script>
对于记录,如果您喜欢更实用的样式和point-free style,那么您可以使用Lodash FPLodash发行版,这会使这一点变得更容易。所有导出的函数都是Currate的,参数也会更改,因此数据始终是最后的。这使您可以更轻松地构建给定数据的处理:
const obj = {a: [{ id: 1 }, {id: 1}, {id: 2}, {id: 3}], b: [{ id: 4 }, {id: 5}, {id: 5}, {id: 6}] };
const process = _.map(_.groupBy("id"));
console.log(process(obj));
.as-console-wrapper { max-height: 100% !important; }
<script src="aHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L2cvbG9kYXNoQDQobG9kYXNoLm1pbi5qcytsb2Rhc2guZnAubWluLmpzKQ=="></script>
这篇关于将_.groupBy传递给_.artialRight似乎给出了不正确的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:将_.groupBy传递给_.artialRight似乎给出了不正确的结果


- 使用RSelum从网站(报纸档案)中抓取多个网页 2022-09-06
- Fetch API 如何获取响应体? 2022-01-01
- CSS媒体查询(最大高度)不起作用,但为什么? 2022-01-01
- 如何使用 JSON 格式的 jQuery AJAX 从 .cfm 页面输出查 2022-01-01
- Css:将嵌套元素定位在父元素边界之外一点 2022-09-07
- 失败的 Canvas 360 jquery 插件 2022-01-01
- addEventListener 在 IE 11 中不起作用 2022-01-01
- Flexslider 箭头未正确显示 2022-01-01
- Quasar 2+Apollo:错误:找不到ID为默认的Apollo客户端。如果您在组件设置之外,请使用ProvideApolloClient() 2022-01-01
- 400或500级别的HTTP响应 2022-01-01