gpt4 book ai didi

javascript - Lodash reduce with includes 或 orderBy iteratee 用例

转载 作者:行者123 更新时间:2023-12-04 09:41:54 25 4
gpt4 key购买 nike

来自 reduce 的 lodash 文档:

_.reduce(collection, [iteratee=_.identity], [accumulator])

Reduces collection to a value which is the accumulated result of running each element in collection thru iteratee, where each successive invocation is supplied the return value of the previous. If accumulator is not given, the first element of collection is used as the initial value. The iteratee is invoked with four arguments: (accumulator, value, index|key, collection).

Many lodash methods are guarded to work as iteratees for methods like _.reduce, _.reduceRight, and _.transform.

The guarded methods are: assign, defaults, defaultsDeep, includes, merge, orderBy, and sortBy

我可以看到如何将 reduce 应用于大多数其他方法,因为它们大致遵循方法签名。例如,assigndefaults 的形式(在非正式的 TypeScript-ish 伪代码中):

_.assign and _.defaults: (object: object, sources: collection) => object
^ accumulator ^ value ^ same type as accumulator

同样,sortBy也是有道理的:

_.sortBy: (collection: object, iteratees: sort_fn[]) => object
^ accumulator ^ value ^ same type as accumulator

我可以看到这些有用的用例,例如:

console.log('reduce',
_.reduce([{a: 2, b: 4}, [123, 52], {a: 5}], _.assign),
_.reduce([{a: 2, b: 4}, [123, 52], {a: 5}], _.defaults),
_.reduce([[e => e.a], [e => e.b]], _.sortBy,
[{a: 3, b: 2}, {a: 3, b: 3}, {a: 2, b: 15}, {a: -2, b: 3}])
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


但是,我不确定这将如何与 orderByincludes 一起使用。即,

_.orderBy: (collection: object, iteratees: sort_fn[], orders: ('asc' | 'desc')[]) => object
^ accumulator ^ value ^ index??? ^ same type as accumulator

查看 source在一些方法调用之后,尽管第三个参数是 'asc' | 的数组,但它似乎仍然有效。 'desc' 值(由于保护,它对其进行特殊处理)。最终,通过保护,它似乎将所有 order 都默认为 asc,因此它的行为就像 sortBy

console.log('reduce',
_.reduce([[e => e.a], [e => e.b]], _.orderBy,
[{a: 3, b: 2}, {a: 3, b: 3}, {a: 2, b: 15}, {a: -2, b: 3}])
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>

因此看起来,如果以这种方式使用,保护不是很有用,只是使它成为 sortBy 的替代品,有效地使 orders 参数无用。

对于 includes,我什至不确定如何将其用作 reducer 函数,因为它的返回类型( bool 值)与其第一个参数不同,例如:

_.includes: (collection: object, value: any) => boolean
^ accumulator ^ value ^ not same type as accumulator?

我的问题是:有没有办法(有效地)使用 _.orderBy_.includes 作为 _.reduce_.transform 迭代器?如果不是,为什么 lodash 文档将它列为可以以这种方式使用的 protected 函数?

抱歉,如果这听起来有点像两个问题,但我认为它们有足够的相关性,因此属于同一类。

最佳答案

TL;DR(完整故事见下文)

我的猜测是在 _.includes 的情况下, 它从来没有打算与 _.reduce 一起使用,相反,这要么是多年前仍然存在的失误,要么是 Unresolved 需要,以更好地阐明文档的这一部分。

相反,他们添加 guard 参数的目的是使其可用于 _.every , _.some以及部分应用时的类似内容。

像这样:

_.every([1, 2], _.partial(_.includes, [1, 2, 3, 4])) // => true
_.every([1, 5], _.partial(_.includes, [1, 2, 3, 4])) // => false

全文

我试图替换我的代码中用一些丑陋的 _.filter 制作的特定部分小号,_.clone s 和 !_.includes用更优雅的东西。

然后,就像我通常在这些情况下所做的那样,我尝试浏览 lodash 文档并尝试激发我大脑中的创造力。

然后我在您提到的文档中找到了同一行,并且在玩了一下 _.reduce 之后和 _.includes ,得出了和你一样的结论。它没有意义。

认为我可能错了,我用谷歌搜索了它,希望我能找到一些聪明的例子并最终来到这里。

很高兴看到我在这个世界上没有疯,或者至少不是一个人疯了,但它仍然没有解决我脑子里的痒,因为这个问题没有答案(因为在我写这篇文章的时候)。

所以我去了剩下的最后一个地方,在那里我可以尝试挖掘一些相关信息:the source code .

找找找找找找找找找找找找找找找找找找找找找找找commit that introduced that change .

其中最有趣的部分是添加到 _.includes 的测试。测试部分:

      strictEqual(_.includes([-0], 0), true);
});

+ test('should work as an iteratee for methods like `_.reduce`', 1, function() {
+ var array1 = [1, 2, 3],
+ array2 = [2, 3, 1];
+
+ ok(_.every(array1, _.partial(_.includes, array2)));
+ });
+
test('should be aliased', 2, function() {
strictEqual(_.contains, _.includes);
strictEqual(_.include, _.includes);

但仔细观察,您会发现它没有测试与 _.reduce 相关的任何内容完全没有!

所以下一站,我去了测试套件并试图找到与该功能相关的任何额外测试,这些测试可以在提交后添加,而且,有趣的是,我发现恰恰相反!

显然,有一天整个测试套件发生了巨大的变化,将所有使用与实际测试函数无关的 lodash 函数的地方替换为从第二个、较旧(且稳定)的 lodash 实例中使用它们,可能是为了避免可能使测试无法捕获的错误 可能会使测试无法捕获可能...的错误

that change , 有人被迫真正关注 _ 的每一点在测试套件中,可能意识到该特定测试的描述根本没有意义。

所以他们改变了它:

       assert.strictEqual(_.includes([0], -0), true);
});

- QUnit.test('should work as an iteratee for methods like `_.reduce`', function(assert) {
+ QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
assert.expect(1);

var array1 = [1, 2, 3],
array2 = [2, 3, 1];

- assert.ok(_.every(array1, _.partial(_.includes, array2)));
+ assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
});
}(1, 2, 3, 4));

最后但同样重要的是,我尝试阅读 _.every 的源代码从在 _.includes 中添加守卫的提交之前的提交开始功能,但这并没有给我预期的快速答案,所以我得到了版本 3.5.0 (这是最后一个在 _.includes 函数中没有更改的版本)来自 CDN,将其直接包含在 <script> 中在一个空页面中标记并快速测试基本上与该测试套件中添加的相同行。

瞧,它没有用。

所以我得出结论,最初的意图可能是使这种情况(使用 _.every 函数)起作用,但在文档中,他们不小心将其添加到 protected 函数列表中以与 _.reduce 一起使用代替功能。或者他们只是依赖于短语中的“methods like”,并认为把它放在那里就足够了,因为它在技术上并没有专门绑定(bind)到_.reduce功能。

无论哪种方式,我都打开了一个问题 here在 lodash 存储库中尝试引起人们的注意。

关于javascript - Lodash reduce with includes 或 orderBy iteratee 用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62295930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com