JavaScript地图和同时找到:findMap? [英] JavaScript map & find at the same time: findMap?

查看:31
本文介绍了JavaScript地图和同时找到: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).

某些语言具有 find_map (例如,

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆