I have a function that scrambles letters based on shuffleLetters.js. It's working great, but I can't seem to exclude classes that are nested in the class that I'm targeting.
So I want to scramble the characters in my menu items. So I give them a class of .shuffle and call the function like so:
$(function(){
var container = $(".shuffle")
container.shuffleLetters();
});
Where .shuffleLetters engages the plugin. The problem is that it's scrambling all the characters that are nested within that menu item, which I don't want.
I've read about the .not method, but can't get it to work properly.
Here's what I'm trying:
<li class="shuffle">title
<li class="no-shuffle">sub-title
</li>
</li>
then I'm writing my js like so (or every possible variation of):
$(function(){
var container = $(".shuffle").not('.no-shuffle')
container.shuffleLetters();
});
This is not working though.
Can anyone point me in the right direction here, racking my brain for hours.
as always, thanks in advance!
Edit: Here's the shuffleLetters.js:
(function($){
$.fn.shuffleLetters = function(prop){
var options = $.extend({
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "", // Use this text instead of the contents
"callback" : function(){} // Run once the animation is complete
},prop)
return this.each(function(){
var el = $(this),
str = "";
// Preventing parallel animations using a flag;
if(el.data('animated')){
return true;
}
el.data('animated',true);
if(options.text) {
str = options.text.split('');
}
else {
str = el.text().split('');
}
// The types array holds the type for each character;
// Letters holds the positions of non-space characters;
var types = [],
letters = [];
// Looping through all the chars of the string
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
el.html("");
// Self executing named function expression:
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
// The animation is complete. Updating the
// flag and triggering the callback;
el.data('animated',false);
options.callback(el);
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at thsi position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
el.text(strCopy.join(""));
setTimeout(function(){
shuffle(start+1);
},1000/options.fps);
})(-options.step);
});
};
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
})(jQuery);
Try wrapping text node "title" in .shuffle li within span element
(function($){
$.fn.shuffleLetters = function(prop){
var options = $.extend({
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "", // Use this text instead of the contents
"callback" : function(){} // Run once the animation is complete
},prop)
return this.each(function(){
var el = $(this),
str = "";
// Preventing parallel animations using a flag;
if(el.data('animated')){
return true;
}
el.data('animated',true);
if(options.text) {
str = options.text.split('');
}
else {
str = el.text().split('');
}
// The types array holds the type for each character;
// Letters holds the positions of non-space characters;
var types = [],
letters = [];
// Looping through all the chars of the string
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
el.html("");
// Self executing named function expression:
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
// The animation is complete. Updating the
// flag and triggering the callback;
el.data('animated',false);
options.callback(el);
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at thsi position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
el.text(strCopy.join(""));
setTimeout(function(){
shuffle(start+1);
},1000/options.fps);
})(-options.step);
});
};
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
})(jQuery);
$(function() {
var container = $(".shuffle span:first")
container.shuffleLetters();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<ul>
<li class="shuffle"><span>title</span>
<ul>
<li class="no-shuffle">sub-title
</li>
</ul>
</li>
</ul>
Related
I started writing this piece of code for InDesign to underline all letters except from the one with descendants, and added a dialog window to chose stroke and offset of the line.
Now I have two problems:
the program underlines all letters
the stroke and offset won't change
I'm a beginner in Javascript and it's the first time coding for InDesign. Does someone have a clue? Thank you!
// UNDERLINE ALL BUT NO DESCENDANTS
//Make certain that user interaction (display of dialogs, etc.) is turned on.
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
if (app.documents.length != 0){
try {
// Run script with single undo if supported
if (parseFloat(app.version) < 6) {
main();
} else {
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Expand State Abbreviations");
}
// Global error reporting
} catch ( error ) {
alert( error + " (Line " + error.line + " in file " + error.fileName + ")");
}
}else{
alert("Open a document first before running this script.");
}
///MAIN FUNCTION
function main(){
if(app.selection.length != 0){
myDisplayDialog();
}
}
//INTERFACE
function myDisplayDialog(){
//declare variables
//general
var myDoc = app.activeDocument;
var mS = myDoc.selection;
// dialog
var myDialog = app.dialogs.add({name:"Underliner"});
var myLabelWidth = 70;
with(myDialog.dialogColumns.add()){
with(borderPanels.add()){
with(dialogColumns.add()){
with(dialogRows.add()){
staticTexts.add({staticLabel:"Stroke:", minWidth:myLabelWidth});
staticTexts.add({staticLabel:"Offset:", minWidth:myLabelWidth});
}
}
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:1, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue: 15, editUnits:MeasurementUnits.points});
}
}
}
var myResult = myDialog.show();
if(myResult == true){
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS,myStroke,myOffset);
}
else{
myDialog.destroy();
alert("Invalid page range.");
}
}
//REAL FUNCTION
function underline(charList,stroke, offset){
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'];
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
//console.log(typeof myText);
if (includes(myChar, doNotUnderline) == false)
{
myChar.underline = true;
myChar.underlineWeight == stroke;
myChar.underlineOffset == offset;
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
//function to know if char is in array
function includes(elemento,array)
{
var len = array.length;
for(var i=0; i<len ;i++)
{
if(array[i]==elemento){return true;}
}
return false;
}
Try these changes in the function underline():
//REAL FUNCTION
function underline(words,stroke, offset) { // <------ here 'words' instead of 'charList'
var charList = words[0].characters; // <------ here get 'characters' of the 'words'
var len = charList.length;
const doNotUnderline = ['g','j','p','q','y'].join(); // <------- here '.join()'
for (var i=0; i < len; i++){
try{
var myChar = charList[i];
// if (includes(myChar, doNotUnderline) == false) // <----- no need
if (doNotUnderline.indexOf(myChar.contents) < 0) // <------ 'indexOf()' instead of 'includes()'
{
myChar.underline = true;
myChar.underlineWeight = stroke; // <------- here '=' instead of '=='
myChar.underlineOffset = offset; // <------- here '=' instead of '=='
} else {
myChar.underline = false;
}
}catch(r){
alert(r.description);
break;
}
}
}
Probably there can be another improvements as well. It's need additional researches. But if you change these lines it should work to a degree.
And there is one little thing that improves user experience greatly: to keep last used values in the input fields. It can be done pretty easy, let me know it you need it.
Update
Here is the way I'm using to store and restore any preferences of my scripts.
Add somewhere at the start of your script these lines:
// get preferences
var PREFS = { stroke: 1, offset: 15 }; // set default prefs
var PREFS_FILE = File(Folder.temp + '/underline_prefs.json'); // the file with preferences
if (PREFS_FILE.exists) PREFS = $.evalFile(PREFS_FILE); // get the prefs from the file
Now you can use the global values PREFS.stroke and PREFS.offset anywhere you want. In your case they go here:
with(dialogRows.add()){
staticTexts.add({staticLabel:""});
var myStroke = measurementEditboxes.add({editValue:PREFS.stroke, editUnits:MeasurementUnits.points});
var myOffset = measurementEditboxes.add({editValue:PREFS.offset, editUnits:MeasurementUnits.points});
}
This way script will get the stroke and weight from the file underline_prefs.json that will be stored in the standard temporary folder of current user.
Final step is to save the values back into the file after the script got them from the dialog window.
I'd put this piece of code here:
if (myResult == true) {
var myStroke = myStroke.editValue;
var myOffset = myOffset.editValue;
myDialog.destroy();
underline(mS, myStroke, myOffset);
// save preferences here
PREFS.stroke = myStroke;
PREFS.offset = myOffset;
PREFS_FILE.open('w');
PREFS_FILE.write(PREFS.toSource());
PREFS_FILE.close();
} else {
myDialog.destroy();
alert("Invalid page range.");
}
Voilá. Now don't need to type the values every time they differ from default ones.
I want to get result from array and check it one by one
//////////////////////////////////////////////
//////////// this code not works, ////////////
//////////// but not flexible ////////////
//////////////////////////////////////////////
var myA = ["said", "imad", "hassan", "bilal", "mohamed"];
var doc = document.getElementById('div1');
var inp = document.getElementById('input1');
function click1() {
'use strict';
var i = inp.value;
if (i <= 0) {
doc.innerHTML = 'Please type name';
} else if (i === myA[0] || i === myA[1] ||
i === myA[2] || i === myA[3] || i === myA[4]) {
doc.innerHTML = i;
} else {
doc.innerHTML = 'Please type in a correct name';
}
}
/////////////////////////////////////////////////////
//////////// my try to make it flexible, ////////////
//////////// but i get just a last index ////////////
/////////////////////////////////////////////////////
var myA = ["said", "imad", "hassan", "bilal", "mohamed"];
var index = myA[0];
// console.log(index);
var doc = document.getElementById('div1');
var inp = document.getElementById('input1');
function getId(a){
var aL = a.length, index = a[0], x=0;
for(x = 0; x < aL; x++ ){
index = a[x];
// console.log(index);
}
return index;
}
// console.log(getId(myA));
function click1() {
'use strict';
var i = inp.value;
if (i <= 0) {
doc.innerHTML = 'Please type name';
} else if (i === getId(myA)) {
doc.innerHTML = i;
} else {
doc.innerHTML = 'Please type in a correct name';
}
}
How to check if a value is in an array:
New style (ES6):
if (myA.includes(inp.value)) {
// name found in array
}
Older style:
if (myA.indexOf(inp.value) > -1) {
// name found in array
}
Your getId() function is simply wrong. The way it's designed, it's looping over your myA array and always returns the last element: mohamed.
You need to feed this function a value to compare, loop over the array and in case it finds a match, return a boolean true. If not make it return false.
function getId(val){
for(var a=0;a<myA.length;a++)
{
if(myA[a]==val)
{
return true;
}
}
return false;
}
Now you can simply call it by
if (getId(i)) {
doc.innerHTML = i;
} else {
doc.innerHTML = 'Please type in a correct name';
}
I've been struggling for the past day trying to solve this one.
I'm trying to get some funky text effects going, basically a glorified string creation.
It writes a line a bit like a billboard and to do it I've used setTimeout.
Thing is I would like to put it in a function so I can reuse it and call it multiple times on different elements.
The problem is that I then need to update the text maybe halfway to a new text.
To do so I clear the timeout, but unless the timer variable is outside the scope it doesn't clear.
I can't really have it outside the function because of practicality;
I'm not sure how many times it is going to be called and it just feels wrong to declare 20 time variables outside the function.
Here's the code working CORRECTLY on one item
(click multiple times to interrupt and restart)
var t;
function writeStats(str,dest) {
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
str = str.split('');
var types = [],
letters = [];
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
clearTimeout(t);
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
//el.text(strCopy.join(""));
el = strCopy.join("");
//console.log(el);
$('.'+dest).text(el);
t = setTimeout(function(){
shuffle(start+1);
},500/options.fps);
})(-options.step);
}
$(document).ready(function(){
$(document).click(function(){
writeStats('this sentence is a great one','t1');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
and a Fiddle script: https://jsfiddle.net/phjzfw15/
If I bring the t variable inside the function like so it doesn't work as before:
function writeStats(str,dest) {
var t;
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
function randomChar(type){
var pool = "";
if (type == "lowerLetter"){
pool = "abcdefghijklmnopqrstuvwxyz0123456789";
}
else if (type == "upperLetter"){
pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
}
else if (type == "symbol"){
pool = ",.?/\\(^)![]{}*&^%$#'\"";
}
var arr = pool.split('');
return arr[Math.floor(Math.random()*arr.length)];
}
str = str.split('');
var types = [],
letters = [];
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
clearTimeout(t);
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
//el.text(strCopy.join(""));
el = strCopy.join("");
//console.log(el);
$('.'+dest).text(el);
t = setTimeout(function(){
shuffle(start+1);
},500/options.fps);
})(-options.step);
}
$(document).ready(function(){
$(document).click(function(){
writeStats('this sentence is a great one','t1');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
... and the relative fiddle if you prefer it there: https://jsfiddle.net/phjzfw15/1/
If you run the snippet you'll see it doesn't work properly anymore.
Clicking repeatedly will show you that the old sentence is still there and it gets overwritten.
How can I get this working clearing the timeout correctly inside the function?
I thought the "t" variable was local to each function and a separate instance of it would have been created?
Thanks!
Ok, here's a dumbed down version (maybe the amount of code was too much before)
CORRECT VERSION
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
var timer;
function writeStats(str, dest) {
$('.'+dest).text('');
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
$(document).ready(function(){
var index = 0;
$(document).click(function(){
writeStats(starr[index],'t1');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
Correct version
<div class="t1">Click anywhere multiple times</div>
NOT WORKING VERSION
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
function writeStats(str, dest) {
var timer;
$('.'+dest).text('');
var options = {
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
}
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
$(document).ready(function(){
var index = 0;
$(document).click(function(){
writeStats(starr[index],'t1');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
NOT WORKING VERSION (please note I just moved the timer declaration inside the function)
<div class="t1">Click anywhere multiple times fast</div>
Finally made it to work.
For posterities...
var starr = [
'bloop the boop',
'cammy the shadow',
'i like cauliflower',
'bro, i kick u hard',
'like measels? I dont.',
'eat fish and pie'
];
var writer = function(){
var timer;
this.writeStat = function(str,dest) {
var options = { "step" : 8, "fps" : 25, "text" : "" }
str = str.split('');
clearTimeout(timer);
var ll = '';
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i, len = str.length, el;
if(start>=len){
return;
}
ll = ll + str[start];
$('.'+dest).text(ll);
timer = setTimeout(function(){
shuffle(start+1);
},1500/options.fps);
})(0);
}
}
$(document).ready(function(){
var index = 0;
w = new writer;
y = new writer;
$(document).click(function(){
w.writeStat(starr[index],'t1');
y.writeStat(starr[index],'t2');
if (index == 5) index = 0; else index++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="t1"></div>
<div class="t2"></div>
I'm try to animate (Shuffle) Pre-Typed Text using This plugin Text Shuffle Plugin
But issue is, this is only work when we type in text box. I want to do that when page load.
Here is its Online demo link. DEMO
Here Is Fiddle Link. Fiddle
Unfortunately I am unable to create its fiddle. I just want the onload effect on pre define 's ID
JS Code
$.fn.shuffleLetters = function(prop){
var options = $.extend({
"step" : 8, // How many times should the letters be changed
"fps" : 25, // Frames Per Second
"text" : "" // Use this text instead of the contents
},prop)
return this.each(function(){
var el = $(this),
str = "";
if(options.text) {
str = options.text.split('');
}
else {
str = el.text().split('');
}
// The types array holds the type for each character;
// Letters holds the positions of non-space characters;
var types = [],
letters = [];
// Looping through all the chars of the string
for(var i=0;i<str.length;i++){
var ch = str[i];
if(ch == " "){
types[i] = "space";
continue;
}
else if(/[a-z]/.test(ch)){
types[i] = "lowerLetter";
}
else if(/[A-Z]/.test(ch)){
types[i] = "upperLetter";
}
else {
types[i] = "symbol";
}
letters.push(i);
}
el.html("");
// Self executing named function expression:
(function shuffle(start){
// This code is run options.fps times per second
// and updates the contents of the page element
var i,
len = letters.length,
strCopy = str.slice(0); // Fresh copy of the string
if(start>len){
return;
}
// All the work gets done here
for(i=Math.max(start,0); i < len; i++){
// The start argument and options.step limit
// the characters we will be working on at once
if( i < start+options.step){
// Generate a random character at this position
strCopy[letters[i]] = randomChar(types[letters[i]]);
}
else {
strCopy[letters[i]] = "";
}
}
el.text(strCopy.join(""));
setTimeout(function(){
shuffle(start+1);
},1000/options.fps);
})(-options.step);
});
};
In the function below I iterate through an array (incidents) which contains of strings. The strings is describing an incident (crime or accidents) that is scrapted from another web app, and what I'm doing is dividing and counting the different crimes / accidents and placing them in an object (INCIDENT_MATCHES).
However, some of the text strings may contain of several of the keywords that I search for (e.g. both "gunfire" and "battery"), but that I don't want. Instead I just want the first found word to be counted, and if more keywords are found they should be ignored.
How could this be done?
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++;
});
You can return false from the "each" handler to stop iteration.
if(matchFound){
matchFound = true;
incidentCounts[type] += 1;
return false;
}
edit — and you'll want (I think) another test outside that, at the end of the outer loop:
j++; // I don't understand what that does ...
if (matchFound) return false;
I found this solution below to work. What I did was the following:
I replaced the second forEach statement with "every"
Put "return false" inside "if(matchFound)"
Added "else { return true; }" so that the loop continues if no match is found.
The code:
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;
}
});