2015-07-14 4 views
0

Рассмотрим очень простой код:Продолжить 2 уровней глубоко в 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объектов и только добавить 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 когда ONE должны быть проигнорированы

Это должно быть возможно без одной функции ...

+5

'continue someLabel'? – dfsq

+0

@dfsq Это вопрос или ответ? – Rudie

+0

Вы переопределяете 'var i' во внутреннем цикле. Используйте другую переменную. –

ответ

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

'oldFonts' и' newFonts' не 'Array ', они 'Array ' с шрифтом 'Font.name', поэтому' indexOf() 'не будет работать. Я вижу, что это совсем не очевидно. Обновленный вопрос. – Rudie

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

Update

Если требование для проверки равенства является более сложным, как было отмечено в комментариях, то что-то немного требуется больше. На мой взгляд, это еще проще, чем оригинальный подход с мечеными петлями:

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; 
+0

'oldFonts' и' newFonts' не 'Array ', они 'Array ' с шрифтом 'Font.name', поэтому' indexOf() 'не будет работать. Я вижу, что это совсем не очевидно. Обновленный вопрос. – Rudie

+0

Обновлен ответ, чтобы иметь дело с более сложным механизмом соответствия. –

+0

Хорошо, это круто =) – Rudie