Consider this very simple code:
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);
}
What it's supposed to do is compare all oldFonts objects with newFonts objects and only add newFont to oldFonts (oldFonts.push) if it doesn't already exist (fb.equals).
oldFonts and newFonts are objects with name and host properties. Both are used in fb.equals() to determine equality. indexOf() won't work.
This is exactly how I'd do it in PHP. It doesn't work in JS, because JS doesn't support continue 2, which means continue 2 levels.
How do I do this in JS??
continue wont do, because it'll still finish the inner loop and end up at the pushbreak won't do, because it'll skip the inner loop and jump straight to the pushbreak someLabel won't do, because I don't want to skip ALL newFonts when ONE must be ignoredThis must be possible without a single function...
The comments demonstrated how to continue to a labeled statement. But as to your original problem, you might be able to solve it more easily:
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));
Update
If the requirement for testing equality is more sophisticated, as noted in the comments, then something slightly more is needed. To my mind, this is still simpler than the original approach with labeled loops:
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));
You can see this on JSFiddle
I can't wait for fat-arrows to be widely available. Here's the equivalent:
var complement = (pred, a, b) => a.filter(x => !b.some(y => pred(x, y)));
var sameName = (a, b) => a.name === b.name;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With