【问题标题】:Continue 2 levels deep in JS继续深入 JS 2 级
【发布时间】:2015-07-14 20:41:13
【问题描述】:

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

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 objectsnewFonts objects 进行比较,并且只将newFont 添加到@987654326 @ (oldFonts.push) 如果它尚不存在 (fb.equals)。

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

这正是我在 PHP 中的做法。在 JS 中不行,因为 JS 不支持continue 2,也就是说继续 2 级。

我如何在 JS 中做到这一点??

  • continue 不会这样做,因为它仍然会完成内部循环并最终到达 push
  • break 不会这样做,因为它会跳过内部循环并直接跳转到 push
  • break someLabel 不会这样做,因为我不想跳过所有 newFonts 当必须忽略一个时

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

【问题讨论】:

标签: javascript loops continue


【解决方案1】:

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

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

更新

如果测试相等性的要求更复杂,如 cmets 中所述,则需要更多的东西。在我看来,这仍然比带有标记循环的原始方法更简单:

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


我等不及要广泛使用胖箭头了。这是等效的:

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

【讨论】:

  • oldFontsnewFonts 不是 Array&lt;String&gt;,它们是 Array&lt;Font&gt;Font.name 是字体,所以 indexOf() 不起作用。我现在看到这根本不明显。更新的问题。
  • 更新了答案以处理更复杂的匹配机制。
【解决方案2】:

也许这样的事情会帮助解决你的问题:

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&lt;String&gt;,它们是 Array&lt;Font&gt;Font.name 是字体,所以 indexOf() 不起作用。我现在看到这根本不明显。更新的问题。
猜你喜欢
  • 1970-01-01
  • 2017-06-04
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多