继续 JS 的 2 个层次

Continue 2 levels deep in JS

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

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 objects 并且只添加 newFontoldFonts (oldFonts.push) 如果它不存在 (fb.equals).

oldFontsnewFonts 是具有 namehost 属性的对象。两者都用于 fb.equals() 以确定相等性。 indexOf() 不行。

这正是我在 PHP 中的做法。它在JS中不起作用,因为JS不支持continue 2,这意味着继续2级。

如何在 JS 中执行此操作?

这必须在没有单一功能的情况下成为可能...

也许这样的事情可以帮助解决您的问题:

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);
}

评论演示了如何继续标记语句。但是对于你原来的问题,你也许可以更容易地解决它:

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));

你可以看到这个on JSFiddle


我等不及 fat-arrows 广泛使用了。这是等效的:

var complement = (pred, a, b) => a.filter(x => !b.some(y => pred(x, y)));
var sameName = (a, b) => a.name === b.name;