JavaScript地图和同时找到:findMap? [英] JavaScript map & find at the same time: findMap?
问题描述
您如何在不使用for循环的情况下重写它?
How would you rewrite this without using a for loop?
const a = [2, 5, 78, 4];
const expensiveFunction = n => 2 * n;
let result;
// Find the first number
for (let i = 0; i < a.length; i++) {
const r = expensiveFunction(a[i]);
if (r > 100) {
result = r;
break;
}
}
console.log(result);
我幼稚的方法:
const result = a.map(expensiveFunction).find(x => x > 100);
console.log(result);
但是这会在所有元素上运行 expensiveFunction
,我想避免这种情况.在上述情况下,我们应该避免运行 expensiveFunction(4)
.
But this runs expensiveFunction
on all the elements, which I would like to avoid. In the above case, we should avoid running expensiveFunction(4)
.
Some languages have find_map
(e.g, Rust), I didn't find it in lodash nor in underscore.
推荐答案
内置的 map
很贪婪,因此您必须编写自己的惰性版本:
Built-in map
is greedy so you have to write your own, lazy version:
const a = [2, 5, 78, 4];
const expensiveFunction = n => {
console.log('expensiveFunction for', n);
return 2 * n
};
function *map(a, fn) {
for(let x of a)
yield fn(x);
}
function find(a, fn) {
for(let x of a)
if (fn(x))
return x;
}
r = find(map(a, expensiveFunction), x => x > 100)
console.log('result', r)
与股票 map
不同,此 map
是生成器,可按需返回(收益)结果,而不是立即处理整个数组.在此示例中, find
和 map
是协程".并玩某种乒乓球游戏,其中 find
查找结果,而 map
则在需要时提供结果.一旦找到满意的代码,它就会退出,
Unlike the stock map
, this map
is a generator and returns (yields) results on demand rather than processing the whole array at once. find
and map
in this example are "coroutines" and play some kind of a ping-pong game where find
asks for results and map
delivers them when asked. As soon as find
is satisfied with what it's got, it quits and so does map
, because nobody is asking for its results anymore.
您还可以将 map
, find
和朋友添加到 IteratorPrototype
中,以使它们可用于所有迭代器,并能够使用点表示法:
You can also add map
, find
and friends to the IteratorPrototype
to make them available for all iterators and be able to use dot notation:
const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
Object.defineProperties(IteratorPrototype, {
map: {
value: function* (fn) {
for (let x of this) {
yield fn(x);
}
},
enumerable: false
},
find: {
value: function (fn) {
for (let x of this) {
if (fn(x))
return x;
}
},
enumerable: false
},
});
//
const a = [2, 5, 78, 4];
const expensiveFunction = n => {
console.log('expensiveFunction', n);
return 2 * n
};
let r = a.values().map(expensiveFunction).find(x => x > 100);
console.log(r)
这是一个基于此技术的小型图书馆: https://github.com/gebrkn/armita
Here's a small library based on this technique: https://github.com/gebrkn/armita
这篇关于JavaScript地图和同时找到:findMap?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!