I am a novice programmer and apologize upfront for the complicated question.
I am trying to create a lexical decision task for experimental research, in which respondents must decide if a series of letters presented on the screen make a “word” or “not a word”. Everything works reasonably well except for the bit where I want to randomly select a word (category A) or nonword (category B) for each of 80 trials from a separate input file (input.txt). The randomization works, but some elements from each list (category A or B) are skipped because I have used “round.catIndex = j;” where “j” is a loop for each successive trial. Because some trials randomly select from Category A and other from Category B, “j” does not move successively down the list for each category. Instead, elements from the Category A list may be selected from something like 1, 2, 5, 8, 9, 10, and so on (it varies each time because of the randomization).
To make a long story short(!), how do I create a counter that will work within the for-loop for each trial, so that every word and nonword from Category A and B, respectively, will be used for the lexical decision task? Everything I have tried thus far does not work properly or breaks the javascript entirely.
Below is my code snippet and the full code is available at http://50.17.194.59/LDT/trunk/LDT.js. Also, the full lexical decision task can be accessed at http://50.17.194.59/LDT/trunk/LDT.php. Thanks!
function initRounds()
{
numlst = [];
for (var k = 0; k<numrounds; k++)
{
if (k % 2 == 0) numlst[k] = 0;
else numlst[k] = 1;
}
numlst.sort(function() {return 0.5 - Math.random()})
for (var j = 0; j<numrounds; j++)
{
var round = new LDTround();
if (numlst[j] == 0)
{
round.category = input.catA.datalabel;
}
else if (numlst[j] == 1)
{
round.category = input.catB.datalabel;
}
// pick a category & stimulus
if (round.category == input.catA.datalabel)
{
round.itemtype = input.catA.itemtype;
round.correct = 1;
round.catIndex = j;
}
else if (round.category == input.catB.datalabel)
{
round.itemtype = input.catB.itemtype;
round.correct = 2;
round.catIndex = j;
}
roundArray[i].push(round);
}
return roundArray;
}
You can use the comma operator to declare multiple variables and execute multiple statements within a single
forloop.In your case, you could do something like:
I chose those verbose variable names to make it more clear. You’d have two separate indices for category A and B, and you compare the sum of the two versus the number of rounds you want to run. Then inside of your
forloop somewhere, you set the booleanincrementAto eithertrueorfalseto indicate which one to increment.That roughly matches what you’re asking for, but I think what you’d prefer is to use a combination of
Math.random,<array>.spliceand<array>.lengthto get a random word/nonword from each list, rather than producing a predictable order for selection. Then you don’t even care what the indices are for the two categories and you can go back to a simplefor(var i = 0; i < numrounds; i++)type of loop.If the latter is what you really want, leave a comment on this answer and I’ll update it with another example.
EDIT:
Okay, I’m assuming that the actual number and order of words and non-words is not really defined by your test, because otherwise a user could pick up the word/non-word pattern and Christmas Tree the test. I’m also assuming that you have two array of words and non-words called
catAandcatBin the global scope. Below is a function that will do the following:catAandcatBarrays. (So you can setnumroundsto+infif you like.).
The function is using the functional programming concept of closures to create a persisted “global-like” variable,
allWordsthat only it can see. The function automatically refreshes the array with all of the words when the length of the array reaches zero (like it is from the start) using the globalscatAandcatB. To use it in a for loop, simply:If you need to guarantee that an equal number of
catAandcatBwords are used, theouterScopefunction will need to keep track of three variables: copies ofcatAandcatB, and an array the same size asnumrounds, half of which aretrueand halffalse.splicerandomly from this true/false array, and then splice randomly from eithercatAorcatBdepending on whether it’strueorfalse. Then you function will need code to “refresh” all of these closure variables, but it would be essentially the same as how the function is written above.Sorry if the function is a bit complex, but you see how easy it is to use, right? 🙂