logic while iterating a list - javascript

Hi I am new to java script and i need help with the logic of the code. I have a list which is read from csv. Now if in the csv Others is in the middle so it appears in the middle. I want that if others exist in the list it should be added in the end. $scope.disconnectRequestReason is the array I am dealing with. $scope.disconnectRequestParameters[i].paramLabel can have the value other.
if($scope.disconnectRequestParameters[i].paramName == 'disconnectReason'){
$scope.disconnectRequestReason[countReason] = $scope.disconnectRequestParameters[i].paramLabel;
countReason++;
}

You could use length($scope.disconnectRequestReason[]) to get the size of the array and use length-1 to assign values to the last element. If there are multiple "others" you would need to keep count of assignments. In this case you would use length - othersCount and increment othersCount accordingly.
Your code would more or less look like this
if($scope.disconnectRequestParameters[i].paramName == 'disconnectReason'){
if($scope.disconnectRequestParameters[i].paramLabel == Others){
$scope.disconnectRequestReason[length - othersCount] = $scope.disconnectRequestParameters[i].paramLabel;
othersCount++;
} else{
$scope.disconnectRequestReason[countReason] = $scope.disconnectRequestParameters[i].paramLabel;
countReason++
}

Related

Finding the value of an array?

I am coding a sequencer that allows you to choose which sound you want to be carried into different parts of the code. I am using an array that holds the sound ID value and if a different sound is selected, the array is reset and the value changes. Initially, I thought using this snippet would work to check what sound has been chosen:
if(sounds == 1){
//insert effect of sound value
}
But, this did nothing. I then tried:
sounds == [1];
but that had no effect at all. What code should be used when trying to execute code based on the value of an array with a single item (if that makes sense)?
Firstly, by writing sounds == 1 you are checking if the size of "sounds" array is 1 or not.
To access the value of the array element itself use:
sounds[0] == n
Count in array starts from 0, and last element will be length of array sounds.length - 1
Now, if I correctly understood your question itself and you want to output certain sound based on which element is chosen from array, then you could use Switch / Case. First iterate through array using for loop. Then declare Switch() expression. Then, write what kind of output / action should happen when case happens.
for (int i = 0; i < values.length; i++) {
Switch (sounds[i]) {
case 1: // imagine sound ID is 1
//output code // this code will get executed
break;
case 2: // sound ID is 2
//output code // this code will get executed
break;
case 3: // sound ID is 2
//output code // this code will get executed
break;
}
}
As far as I understand your concern, You want to check the value inside the array right?
In that way, You can check the values of the array by using includes() method.
Like:
sounds = [1,2,3,4,5,6];
if(sounds.includes(1)) {
//insert effect of sound value
} else {
// Do else thing here.
}
This might resolve your issue.
Based on our question, you are saying you have an array of sound values. I imagine it looks like
var sounds = ["1"]
If this is the case, you can do sounds.includes("1") to see it "1" is present.

Adding breaks in an array

I'm trying to have there be a line break between each item in my array. What my program does is create a new array using a few others which are based on the users answer to a question. I can't seem to figure out how to allow a line break between each item.
It's all done in JavaScript (with the exception of a little CSS but unimportant). I've tried using the < br > tag but it would just print the < br > instead.
I have four relevant arrays.
One for the questions:
var questions = ["Do you like volunteering","Would you be interested in joining the musical/theatre?","Would you..."] //it goes on and on but I'll spare you
Another for all of the possible results:
var clubs=[["All In","Interact Club","Key Club"," Environmental Club"],[" Fall Production"," Spring Musical"], "Student Government"," Tricorn"] //also goes on for a while
An empty array called recClubs which gets filled as they make choices.
And an empty array called choices for the choices themselves.
Then a little later I print the final outcome:
function endQuizDiv(){
//header of screen
document.getElementById("question").innerHTML= "These are the clubs that you might be interested in";
//prints the recommended clubs
document.getElementById("recClubs").innerHTML= recClubs;
}
And here is where recClubs gets its information:
function eliminateClubs(){
for(h=0;h<=personChoices.length;h++){
if (personChoices[h]==1){
recClubs.push(clubs[h]);
}
}
}
When recClubs is given to the user, all of the clubs are in one block of text and separated by commas. I want them to be separated by a line break. Any help is appreciated.
You could use join for array recClubs.push(clubs[h].join(', <br/>')); Actually you are adding array to innerHtml but it might be formatted string instead with <br/> tags
But data strucure should be :
var clubs=[["All In","Interact Club","Key Club"," Environmental Club"],[" Fall Production"," Spring Musical"], ["Student Government"],[" Tricorn"]].
or without changing data structure
function eliminateClubs(){
for(h=0;h<=personChoices.length;h++){
if (personChoices[h]==1){
var addedValue = Array.isArray(clubs[h]) ? clubs[h].join(', <br/>') :clubs[h] + '<br/>';
recClubs.push(addedValue);
}
}

Javascript looping, using array keys as condition statements - possible?

Is there a way to specify array index key positions so that I can use them as conditional statements in a javascript loop?
I have a string of coordinates, that keeps growing every time the user selects a grid polygon on a map. I take the string & turn it into an array. I am building a text file (dxf format) and as such I have separated the header info, the closing info & made other variables of key positions:
var oneUnit = (coord_array[0])+'\r\n 20\r\n'+(coord_array[1])+'\r\n 11\r\n'+(coord_array[2])+'\r\n 21\r\n'+(coord_array[3])+'\r\n 0\r\nLINE\r\n 8\r\nUnit\r\n 6\r\nCONTINUOUS\r\n 62\r\n1\r\n 10\r\n'+(coord_array[2])+'\r\n 20\r\n'+(coord_array[3])+'\r\n 11\r\n'+(coord_array[4])+'\r\n 21\r\n'+(coord_array[5])+'\r\n 0\r\nLINE\r\n 8\r\nUnit\r\n 6\r\nCONTINUOUS\r\n 62\r\n1\r\n 10\r\n'+(coord_array[4])+'\r\n 20\r\n'+(coord_array[5])+'\r\n 11\r\n'+(coord_array[6])+'\r\n 21\r\n'+(coord_array[7])+'\r\n 0\r\nLINE\r\n 8\r\nUnit\r\n 6\r\nCONTINUOUS\r\n 62\r\n1\r\n 10\r\n'+(coord_array[6])+'\r\n 20\r\n'+(coord_array[7])+'\r\n 11\r\n'+(coord_array[8])+'\r\n 21\r\n'+(coord_array[9])+'\r\n 0\r\nTEXT\r\n 8\r\nUnit\r\n 10\r\n'+(coord_array[0])+'\r\n 20\r\n'+(coord_array[1])+'\r\n 40\r\n85.0\r\n 1\r\n'+(name_array[0])+'\r\n';
I have done this for a user selection of 3 units -so my index has grown to 29.
How do I construct a loop that will specify keys so that the code produces a specific return?
if (coord_array = i > 9 + < 20 ) {
download_file('data.dxf', 'text/dxf', (dxfHeader)+(oneUnit)+(twoUnit)+(dxfCloser));
}
else if (coord_array = i > 20 < 30 ) {
download_file('data.dxf', 'text/dxf', (dxfHeader)+(oneUnit)+(twoUnit)+(threeUnit)+(dxfCloser));
}
else {
download_file('data.dxf', 'text/dxf', (dxfHeader)+(oneUnit)+(dxfCloser));
}
If anyone has tried this - or knows of a more elegant way of dealing with this - I would be happy to hear about it.
It does work somewhat but my condition statements are faulty as when I try picking three grid units, it returns only the first file (which is populating only two) - and for the last creates extra coordinates as undefined.....

How to reference an array in a function argument

I have a series of arrays that contain words I want to use as text in various HTML divs (there are about 35 of these, I included only a few for brevity).
var bodyplan = ['Anguilliform', 'Compressiform', 'Depressiform', 'Filiform', 'Fusiform', 'Globiform', 'Sagittiform', 'Taeniform'];
var mouthposition = ["Inferior", "Jawless", "Subterminal", "Superior", "Terminal"];
var barbels = ['1', '2', '4 or more'];
var caudalshape = ['Continuous', 'Emarginate', 'Forked', 'Lunate', 'Rounded', 'Truncate'];
I have a switch function that is supposed to change the text based on user selections:
switch(n){
case 1:
changelabels(bodyplan, 8);
break;
case 2:
changelabels(mouthposition, 5);
break;
case 3:
changelabels(barbels, 3);
break;
case 4:
changelabels(caudalshape, 6);
break;
case 5:
changelabels(dorsalspines, 8);
break;
default:
alert("handquestsel error")}};
Finally, I have the function which I would like to make the changes (except it doesn't):
function changelabels(opt1,opt2){
var i = opt2;
var im = opt2 - 1;
var c = 1;
var index = 0;
while (i>=c){
var oldlbl = document.getElementById("rb" + c + "lbl");
var newlbla = opt1.slice(im,i);
var newlblb = opt1.toString();
oldlbl.innerHTML = newlblb;
c = c + 1
index = index + 1
}};
I know the code for my function is just plain wrong at this point, but I have altered it so many times that I'm not sure what's going on anymore. At one point I did have the function able to change the text, but it did so incorrectly (it parsed the name of the array, not extracted a value from the array as I wished). Please help. I know I am overlooking some fundamental concepts here, but am not sure which ones. I've lost count of the hours I've spent trying to figure this out. It's seems like it should be so simple, yet in all my chaotic attempts to make it work, I have yet to stumble on an answer.
EDIT: I want my switch statement to call the function and pass to the function, the appropriate array from which to pull the labels from. The purpose of the app is to help a user learn to identify fish. When the user makes selections on the page, a series of pictures will be shown for various character states with an accompanying label describing the state. For example, when the user selects Mouth Position a series of divs will show the different mouth positions that fish have and have a label below the picture to tell the user what that certain character state is called. I can get the pictures to change just fine, but I am having a hell of a time with the labels.
Why not just something along the lines of:
document.getElementById("bodyplan_label").innerHTML = bodyplan[bodyplan_index];
You seem trying to put everything in really abstract data structures, I see no reason to. Just keep it simple.
Also bodyplan has only 8 elements, so bodyplan[8] will give you an out of bounds exception because arrays start at 0 as is common in all modern programming languages.
If I'm reading your requirement and code correctly, in your switch statement you are passing both a reference to the appropriate array and that array's expected length - you don't need the second parameter because all JavaScript arrays have a .length property.
You don't want to use .slice() to get the individual values out of the array, because that returns a new array copied out of the original - just use arrayVariable[index] to get the individual item at index.
So, putting that together try something like this (with your existing array definitions):
switch(n){
case 1:
changelabels(bodyplan);
break;
case 2:
changelabels(mouthposition);
// etc.
}
function changelabels(data) {
var i,
lbl;
for (i = 0; i < data.length; i++) {
lbl = document.getElementById("rb" + (i+1) + "lbl");
lbl.innerHTML = data[i];
}
}
Notice how much simpler that is than your code? I'm assuming here the elements you are updating have an id in the format "rb1lbl", "rb2lbl", etc, with numbering starting at 1: I'm getting those ids using (i+1) because JavaScript array indexes start at zero. Note also that you don't even need the lbl variable: you could just say document.getElementById("rb" + (i+1) + "lbl").innerHTML = data[i] - however I've left it in so that we have something to expand on below...
Within your function you seem to be changing the labels on a set of elements (radio button labels?), one per value in the array, but you stop when you run out of array items which means any leftover elements will still hold the values from the previous selection (e.g., if the previous selection was "bodyplan" with 8 options and you change to "mouthposition" with only 5 - you probably should hide the 3 leftover elements that would otherwise continue to display the last few "bodyplan" items. One way to do that is instead of setting your loop up based on the array length you could loop over the elements, and if the current element has an index beyond the end of the array hide it, something like this:
function changelabels(data) {
var i,
lbl,
elementCount = 20; // or whatever your element count is
for (i = 0; i < elementCount; i++) {
lbl = document.getElementById("rb" + (i+1) + "lbl");
if (i < data.length) {
lbl.innerHTML = data[i];
lbl.style.display = "";
} else {
lbl.innerHTML = "";
lbl.style.display = "none";
}
}
}
If these elements are labels for radio buttons (just a guess based on the ids) then you'd also want to hide or show the corresponding radio buttons, but I hope you can figure out how to add a couple of lines to the above to do that.
(As mentioned above, be careful about having element ids count up from 1 when the array indexes start at 0.)
If the above doesn't work please post (at least some of) the relevant HTML - obviously I've just had to guess at what it might be like.
SOLUTION: Changed the scope of the array variables to local by moving them into the function where they are used, instead of having them as global variables at the top of the page. I don't understand as I was following every rule of variable declaration. But for some unknown reason, global variables in javascript are abhorrent.
Solution Edit: Found an error in declaring my global variables. This may have been the source of my problem of why I could not access them. But it is a non-issue at this point since I corrected my code.
I don't understand what your trying to achieve exactly with your code. But to pass a variable (in this case an array) by reference you just have to add "&" before the variable.
function the_name(&$var_by_ref, $var_by_value) {
// Here if you modify $var_by_ref this will change the variable passed to the function.
}
More: http://php.net/manual/en/language.references.pass.php
Hope that helps.

Removing items from data bound array

How do I remove an items from a data bound array? My code follows.
for(var i = 0; i < listBox.selectedIndices.length; i++) {
var toRemove = listFiles.selectedIndices[i];
dataArray.splice(toRemove, 1);
}
Thanks in advance!
Edit Here is my swf. The Add Photos works except when you remove items.
http://www.3rdshooter.com/Content/Flash/PhotoUploader.html
Add 3 photos different.
Remove 2nd photo.
Add a different photo.
SWF adds the 2nd photo to the end.
Any ideas on why it would be doing this?
Edit 2 Here is my code
private function OnSelectFileRefList(e:Event):void
{
Alert.show('addstart:' + arrayQueue.length);
for each (var f:FileReference in fileRefList.fileList)
{
var lid:ListItemData = new ListItemData();
lid.fileRef = f;
arrayQueue[arrayQueue.length]=lid;
}
Alert.show('addcomplete:' + arrayQueue.length);
listFiles.executeBindings();
Alert.show(ListItemData(arrayQueue[arrayQueue.length-1]).fileRef.name);
PushStatus('Added ' + fileRefList.fileList.length.toString() + ' photo(s) to queue!');
fileRefList.fileList.length = 0;
buttonUpload.enabled = (arrayQueue.length > 0);
}
private function OnButtonRemoveClicked(e:Event):void
{
for(var i:Number = 0; i < listFiles.selectedIndices.length; i++) {
var toRemove:Number = listFiles.selectedIndices[i];
//Alert.show(toRemove.toString());
arrayQueue.splice(toRemove, 1);
}
listFiles.executeBindings();
Alert.show('removecomplete:' + arrayQueue.length);
PushStatus('Removed photos from queue.');
buttonRemove.enabled = (listFiles.selectedItems.length > 0);
buttonUpload.enabled = (arrayQueue.length > 0);
}
It would definitely be helpful to know two things:
Which version of ActionScript are you targeting?
Judging from the behavior of your application, the error isn't occurring when the user removes an item from the list of files to upload. Looks more like an issue with your logic when a user adds a new item to the list. Any chance you could post that code as well?
UPDATE:
Instead of: arrayQueue[arrayQueue.length]=lid
Try: arrayQueue.push(lid)
That will add a new item to the end of the array and push the item in to that spot.
UPDATE 2:
Ok, did a little more digging. Turns out that the fileList doesn't get cleared every time the dialog is opened (if you're not creating a new instance of the FileReferenceList each time the user selects new files). You need to call splice() on the fileList after you add each file to your Array.
Try something like this in your AddFile() method...
for(var j:int=0; j < fileRefList.fileList.length; j++)
{
arrayQueue.push(fileRefList.fileList[j]);
fileRefList.fileList.splice(j, 1);
}
That will keep the fileList up to date rather than holding on to previous selections.
I see one issue. The selected indices are no longer valid once you have spliced out the first element from the array. But that should only be a problem when removing multiple items at once.
I think we need to see more code about how you are handling the upload before we can figure out what is going on. It looks to me like you are holding a reference to the removed FileReference or something. The described problem is occurring when you upload a new file, not when you remove the selected one.
Do you mean to use listBox and listFiles to refer to the same thing?
I'm stepping out on a limb here, because I don't have a ton of experience with JavaScript, but I'd do this the same way that I'd do it in C, C++, or Java: By copying the remaining array elements down into their new locations.
Assuming that listFiles.selectedIndices is sorted (and its contents are valid indices for dataArray), the code would be something like the following:
(WARNING: untested code follows.)
// Don't bother copying any elements below the first selected element.
var writeIndex = listFiles.selectedIndices[0];
var readIndex = listFiles.selectedIndices[0] + 1;
var selectionIndex = 1;
while(writeIndex < (dataArray.length - listFiles.selectedIndices.length)) {
if (selectionIndex < listFiles.selectedIndices.length) {
// If the read pointer is currently at a selected element,
// then bump it up until it's past selected range.
while(selectionIndex < listFiles.selectedIndices.length &&
readIndex == listFiles.selectedIndices[selectionIndex]) {
selectionIndex++;
readIndex++;
}
}
dataArray[writeIndex++] = dataArray[readIndex++];
}
// Remove the tail of the dataArray
if (writeIndex < dataArray.length) {
dataArray.splice(writeIndex, dataArray.length - writeIndex);
}
EDIT 2009/04/04: Your Remove algorithm still suffers from the flaw that as you remove items in listFiles.selectedIndices, you break the correspondence between the indices in arrayQueue and those in listFiles.selectedIndices.
To see this, try adding 3 files, then doing "Select All" and then hit Remove. It will start by removing the 1st file in the list (index 0). Now what had been the 2nd and 3rd files in the list are at indices 0 and 1. The next value taken from listFiles.selectedIndices is 1 -- but now, what had been the 3rd file is at index 1. So the former File #3 gets spliced out of the array, leaving the former 2nd file un-removed and at index 0. (Using more files, you'll see that this implementation only removes every other file in the array.)
This is why my JavaScript code (above) uses a readIndex and a writeIndex to copy the entries in the array, skipping the readIndex over the indices that are to be deleted. This algorithm avoids the problem of losing correspondence between the array indices. (It does need to be coded carefully to guard against various edge conditions.) I tried some JavaScript code similar to what I wrote above; it worked for me.
I suspect that the problem in your original test case (removing the 2nd file, then adding another) is analogous. Since you've only shown part of your code, I can't tell whether the array indices and the data in listFiles.selectedIndices, arrayQueue, and fileRefList.fileList are always going to match up appropriately. (But I suspect that the problem is that they don't.)
BTW, even if you fix the problem with using splice() by adjusting the array index values appropriately, it's still an O(N2) algorithm in the general case. The array copy algorithm is O(N).
I'd really need to see the whole class to provide a difinitive answer, but I would write a method to handle removing multiple objects from the dataProvider and perhaps assigning a new array as the dataProvider for the list instead of toying with binding and using the same list for the duration. Like I said, this is probably inefficient, and would require a look at the context of the question, but that is what I would do 9unless you have a big need for binding in this circumstance)
/**
* Returns a new Array with the selected objects removed
*/
private function removeSelected(selectedItems:Array):Array
{
var returnArray:Array = []
for each(var object:Object in this.arrayQueue)
{
if( selectedItems.indexOf(object)==-1 )
returnArray.push( object )
}
return returnArray;
}
You might be interested in this blog entry about the fact that robust iterators are missing in the Java language.
The programming language, you mentioned Javascript, is not the issue, it's the concept of robust iterators that I wanted to point out (the paper actually is about C++ as the programming language).
The [research document]() about providing robust iterators for the ET++ C++ framework may still e helpful in solving your problem. I am sure the document can provide you with the necessary ideas how to approach your problem.

Categories