2013-02-18 4 views
1

В приведенной ниже функции я повторяю массив (инциденты), который содержит строки. Строки описывают инцидент (преступление или несчастные случаи), который вырывается из другого веб-приложения, а то, что я делаю, делит и подсчитывает различные преступления/несчастные случаи и помещает их в объект (INCIDENT_MATCHES).Получить только одно совпадение с regexp

Однако некоторые текстовые строки могут содержать несколько ключевых слов, которые я ищу (например, «стрельба» и «батарея»), но этого я не хочу. Вместо этого я просто хочу, чтобы первое найденное слово подсчитывалось, и если найдено больше ключевых слов, их следует игнорировать.

Как это можно сделать?

var INCIDENT_MATCHES = { 
    battery: /\w*(bråk)\w*|överfall|slagsmål|slogs|misshandel|misshandlad|\w*(tjuv)\w*/ig, 
    burglaries: /snattade|snattare|snatta|inbrott|bestulen|stöld|\w*(tjuv)\w*/ig, 
    robberies: /\w*(rån)\w*|personrån|\w*(ryckning)\w*|väskryckt*/ig, 
    gunfire: /skottlossning|skjuten|sköt/ig, 
    drugs: /narkotikabrott/ig, 
    vandalism: /skadegörelse|klotter|\w*(klottra)\w*/ig, 
    trafficAccidents: /(trafik|bil)olycka|(trafik|bil)olyckor|\w*(personbil)\w*|singelolycka|kollision|\w*(kollidera)\w*|påkörd|trafik|smitningsolycka/ig, 
}; 

var j = 0, 
incidentCounts = {}, 
incidentTypes = Object.keys(INCIDENT_MATCHES); 

incidents.forEach(function(incident) { 
    matchFound = false; 

    incidentTypes.forEach(function(type) { 
     if(typeof incidentCounts[type] === 'undefined') { 
      incidentCounts[type] = 0; 
     } 
     var matchFound = incident.match(INCIDENT_MATCHES[type]); 

     if(matchFound){ 
      matchFound = true; 
      incidentCounts[type] += 1; 
     } 
    }); 

    j++; 
}); 

ответ

1

Вы можете вернуть false из «каждого» обработчика, чтобы остановить итерации.

if(matchFound){ 
     matchFound = true; 
     incidentCounts[type] += 1; 
     return false; 
    } 

редактировать — и вы хотите (я думаю), еще один тест за пределами этого, в конце внешнего цикла:

j++; // I don't understand what that does ... 
    if (matchFound) return false; 
+0

На самом деле это не останавливает отсчет по какой-то причине. Одна и та же строка проверяется на совпадения снова, даже после того, как найдено совпадение. – holyredbeard

+0

@holyredbeard ah well, может быть, вам нужно другое 'return false;' для внешнего «цикла» ('.each()') - я обновлю ответ. – Pointy

+0

Я экспериментировал с вашим решением и обнаружил, что изменение второго слова «forEach» на «каждый», ставя «return false» внутри if (matchFound), и после этого положил «else {return true;}», сделал трюк! – holyredbeard

0

Я нашел это решение ниже, чтобы работать. То, что я сделал следующее:

  1. Я заменил второе утверждение Foreach с «каждым»
  2. Пут «возвращение ложным» внутри «если (matchFound)»
  3. Добавлено «еще {возвращает истину;}» так что цикл продолжается, если совпадение не найдено.

Код:

incidents[2].forEach(function(incident) { 
    matchFound = false; 

    incidentTypes.every(function(type) { 
     if(typeof crimesPerType[type] === 'undefined') { 
      crimesPerType[type] = 0; 
    } 
    var matchFound = incident.match(INCIDENT_MATCHES[type]); 

    if(matchFound){ 
     crimesPerType[type] += 1; 
     if (type == 'trafficAccidents') { 
      incidents[3][j].push('traffic'); 
     } 
     else { 
      incidents[3][j].push('crime'); 
     } 
     return false; 
    } 
    else { 
     return true; 
    } 
}); 
Смежные вопросы