且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

将_.groupBy传递给_.artialRight似乎给出了不正确的结果

更新时间:2022-04-14 01:10:50

_.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="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></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="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></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="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></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="https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)"></script>