继续 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 并且只添加 newFont
到 oldFonts
(oldFonts.push
) 如果它不存在 (fb.equals
).
oldFonts
和 newFonts
是具有 name
和 host
属性的对象。两者都用于 fb.equals()
以确定相等性。 indexOf()
不行。
这正是我在 PHP 中的做法。它在JS中不起作用,因为JS不支持continue 2
,这意味着继续2级。
如何在 JS 中执行此操作?
continue
不行,因为它仍然会完成内部循环并最终到达 push
break
不行,因为它会跳过内部循环并直接跳转到 push
break someLabel
不行,因为我不想在必须忽略一个 时跳过所有 newFonts
这必须在没有单一功能的情况下成为可能...
也许这样的事情可以帮助解决您的问题:
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;
考虑这个非常简单的代码:
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 并且只添加 newFont
到 oldFonts
(oldFonts.push
) 如果它不存在 (fb.equals
).
oldFonts
和 newFonts
是具有 name
和 host
属性的对象。两者都用于 fb.equals()
以确定相等性。 indexOf()
不行。
这正是我在 PHP 中的做法。它在JS中不起作用,因为JS不支持continue 2
,这意味着继续2级。
如何在 JS 中执行此操作?
continue
不行,因为它仍然会完成内部循环并最终到达push
break
不行,因为它会跳过内部循环并直接跳转到push
break someLabel
不行,因为我不想在必须忽略一个 时跳过所有
newFonts
这必须在没有单一功能的情况下成为可能...
也许这样的事情可以帮助解决您的问题:
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;