在JavaScript中继续深入2个级别

3

考虑这个非常简单的代码:

someLabel:
for (var i=0; i<newFonts.length; i++) {
    var newFont = newFonts[i];

    for (var j=0; j<oldFonts.length; j++) {
        var oldFont = oldFonts[j];

        if (fb.equals(oldFont, newFont)) {
            // Break out of inner loop, don't finish outer iteration, continue with next outer item
            continue 2;
        }
    }

    // This must only happen if `newFont` doesn't match ANY `oldFonts`
    oldFonts.push(newFont);
}

它的作用是比较所有的“oldFonts”对象和“newFonts”对象,并且只有在“newFont”不存在于“oldFonts”中时才将其添加到“oldFonts”(使用“oldFonts.push”)中。
“oldFonts”和“newFonts”都是具有“name”和“host”属性的对象。两者都在“fb.equals()”中用于确定相等性。“indexOf()”无法工作。
这正是我在PHP中所做的。在JS中不起作用,因为JS不支持“continue 2”,这意味着继续2级。
我该如何在JS中实现这一点?
- “continue”行不通,因为它仍会完成内部循环并最终到达“push”。 - “break”不起作用,因为它将跳过内部循环并直接跳转到“push”。 - “break someLabel”不适用,因为我不想在必须忽略一个对象时跳过所有“newFonts”。
这必须能够在没有任何单个函数的情况下实现...

7
继续一些标签? - dfsq
@dfsq 这是一个问题还是一个答案? - Rudie
你正在内部循环中重新定义 var i。请使用另一个变量。 - GOTO 0
2
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/continue#Using_continue_with_a_label - Zimmi
@GOTO0 很好的观点。问题已更新。 - Rudie
显示剩余2条评论
2个回答

2

这些注释演示了如何继续执行带标签的语句。但是针对您的原始问题,您可能能够更轻松地解决它:

var difference = function(x, y) {
    return x.filter(function(e) {return y.indexOf(e) < 0;});
};

// or oldFonts = ... if you prefer to mutate
var combinedFonts = oldFonts.concat(difference(newFonts, oldFonts));

更新

如果测试相等的要求更加复杂,正如评论中所指出的那样,则需要稍微多做一些工作。在我看来,这仍然比使用标记循环的原始方法更简单:

var complement = function(pred, a, b) {
    return a.filter(function(x) {
        return !b.some(function(y) {return pred(x, y);});
    });
};

var sameName = function(a, b) {return a.name === b.name;};

var combinedFonts = oldFonts.concat(complement(sameName, newFonts, oldFonts));

你可以在JSFiddle上查看此内容:http://jsfiddle.net/CrossEye/6pzojhs1/
我迫不及待想要广泛使用fat-arrows。以下是等价的代码:
var complement = (pred, a, b) => a.filter(x => !b.some(y => pred(x, y)));
var sameName = (a, b) => a.name === b.name;

oldFontsnewFonts不是Array<String>,而是具有Font属性的Array<Font>,其中Font.name是字体,因此indexOf()无法使用。我现在看到这一点并不明显。更新了问题。 - Rudie
更新了答案以处理更复杂的匹配机制。 - Scott Sauyet

0

也许像这样的代码可以帮助你解决问题:

var oldfonts = ['courier new', 'comic sans', 'century gothic'];
var newfonts = ['times new roman', 'comic sans', 'wingdings'];
var addfonts = [];
for (var i = 0; i < newfonts.length; i++) {
    if (oldfonts.indexOf(newfonts[i]) < 0) { // if newfonts item doesnt exist in oldfonts array
        addfonts.push(newfonts[i]); // add it to addfonts array to be added to oldfonts array systematically after all different font items are found           
    }
}
for(var i = 0; i < addfonts.length; i++) {
    oldfonts.push(addfonts[i]); // push add fonts to oldfonts array
    console.log(oldfonts);
}

oldFontsnewFonts不是Array<String>,它们是具有Font.name作为字体的Array<Font>,因此indexOf()无法工作。我现在明白这一点,这一点根本不明显。已更新问题。 - Rudie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接