Javascript 对typescript映射的迭代失败

Javascript 对typescript映射的迭代失败,javascript,typescript,iterator,Javascript,Typescript,Iterator,我正在使用下面的函数比较两张地图。有趣的是for循环中的代码从未执行过。所以,console.log(key,val)code永远不会执行。当然,我确保我正在比较的映射不是空的,并且具有相同的大小,以强制执行for循环中的代码。我是犯了一个很愚蠢的错误还是错过了一个深刻的概念 private compareMaps(map1, map2) { var testVal; if (!(map1 && map2)) { retur

我正在使用下面的函数比较两张地图。有趣的是for循环中的代码从未执行过。所以,
console.log(key,val)
code永远不会执行。当然,我确保我正在比较的映射不是空的,并且具有相同的大小,以强制执行for循环中的代码。我是犯了一个很愚蠢的错误还是错过了一个深刻的概念

private compareMaps(map1, map2) {
        var testVal;
        if (!(map1 && map2)) {
            return false;
        }
        if (map1.size !== map2.size) {
            return false;
        }
        for (var [key, val] of map1) {
            testVal = map2.get(key);
            console.log(key, val);
            if (testVal !== val || (testVal === undefined && !map2.has(key))) {
                return false;
            }
        }
        return true;
    }
有趣的是for循环中的代码从未执行过。我是犯了一个很愚蠢的错误还是错过了一个深刻的概念

private compareMaps(map1, map2) {
        var testVal;
        if (!(map1 && map2)) {
            return false;
        }
        if (map1.size !== map2.size) {
            return false;
        }
        for (var [key, val] of map1) {
            testVal = map2.get(key);
            console.log(key, val);
            if (testVal !== val || (testVal === undefined && !map2.has(key))) {
                return false;
            }
        }
        return true;
    }
你错过了一个事实

在ES6之前的TypeScript中,
for…of
不适用于
Map
当它以ES6之前的ECMAScript为目标时,TypeScript编译器将语句的for…转换为一个for循环

此代码:

for (var [key, val] of map) {
    console.log(key);
}
for (var _i = 0, map_1 = map; _i < map_1.length; _i++) {
    var _a = map_1[_i], key = _a[0], val = _a[1];
    console.log(key);
}
成为以下代码:

for (var [key, val] of map) {
    console.log(key);
}
for (var _i = 0, map_1 = map; _i < map_1.length; _i++) {
    var _a = map_1[_i], key = _a[0], val = _a[1];
    console.log(key);
}
选项2:当我们必须在ES6之前以ECMAScript为目标,并且我们必须对的…具有确切的
行为时,将
映射
转换为
数组
,并使用
的…进行迭代

选项3:当我们可以确定目标时,直接在
地图上使用
for…of
循环

旁白:地图平等

如果要求是MAP等式,请考虑。这就解决了在迭代过程中需要

中断
的问题,因为
每一个
在找到第一个
false
时都会立即返回

如果顺序对比较很重要,请按如下方式使用
每个

function areEqual<K,V>(map1: Map<K,V>, map2: Map<K,V>) { 
    if(!map1 || !map2) return false;
    const array1 = Array.from(map1.entries());
    const array2 = Array.from(map2.entries());
    return array1.every(([k1, v1], index) => {
        const [k2, v2] = array2[index];
        return k1 === k2 && v1 === v2;
    });
}
以下是正在运行的功能的演示:

const map1 = new Map([["key1", "val1"], ["key2", "val2"]]);
const map2 = new Map([["key1", "val1"], ["key2", "val2"]]);
const map3 = new Map([["key2", "val2"], ["key1", "val1"]]);

console.log(areEqual(map1, map2)); // true
console.log(areEqual(map1, map3)); // false
console.log(areSetEqual(map1, map2)); // true
console.log(areSetEqual(map1, map3)); // true

一个
用于。。。of
循环可以通过一个iterable,而
Map
本身不是iterable。您可以使用
条目
方法将其转换为iterable(然后可以进一步转换为数组)

例如,要获取按插入顺序表示贴图关键点的数组,可以:

let keys = Array.from(map1.keys());
然后,您可以使用
for来迭代此
数组。。。属于
循环,因为数组是一个iterable:

for (var key of keys) {
    testVal = map2.get(key);
    console.log(key, val);

    if (testVal !== val || (testVal === undefined && !map2.has(key))) {
        return false;
    }
}


不过有趣的是,我相信不必创建数组就可以实现这一点,也就是说,只需使用
for(让map1.keys()的key)
,因为
.keys()
本身会返回一个iterable,但TypeScript似乎在处理这一点上存在问题(至少在ES5中,没有在ES6 target中尝试).

如果我比较两个带有字符串key和value的映射,这似乎在typescript中起作用

private compareMaps(map1, map2) {
        var testVal;
        if (!(map1 && map2)) {
            return false;
        }
        if (map1.size !== map2.size) {
            return false;
        }
        for (let key of Array.from(map1.keys())) {
            let val = map1.get(key);
            testVal = map2.get(key);
            if (testVal !== val || (testVal === undefined && !map2.has(key))) {
                return false;
            }
        }
        return true;
    }

在javascript中,它正在工作。是的,我正在使用map。我打印了我正在比较的地图,它们是这样的:
Map(5){“gender”=>“men”,“category”=>“D”,“1”=>“11”,“2”=>“21”,“3”=>“32”}
Map(5){“gender”=>“men”,“category”=>“D”,“1”=>“11”,“2”=>“21”,“3”=>“33”}
@JohnWeisz谢谢你。我发现了问题。@quantdaddy——不,在
forEach
回调中的
return
语句本质上与循环中的
continue
相同,并且没有直接等价的
break
。@JohnWeisz这背后有什么逻辑吗?return语句总是用来停止运行代码块,对吗?除了抛出异常之外,没有其他方法可以停止或中断forEach()循环。如果我比较两个映射的条目,可能我可以使用map2.get(“key”)在每次迭代中获得第二个映射的值。让我试试。