Pushing object to array results in same value - javascript

I have the following javascript code that does not work as I would expect it to. I have a list of checkboxes of which two of the items are "TestDuration" and "AssessmentScores". I'm trying to iterate through the list (which works fine) and have it add the values that are checked to the array.
var SAIndex = 0;
var SSIndex = 0;
var ScoresIndex = 0;
var SubAssessments = [];
var SubAssessmentScores = [];
//Get to the container element
var SSList = document.getElementById("islSubAssessmentScore_container");
//turn it into an array of the checkbox inputs
SSList = SSList.getElementsByTagName("input");
//create a temporary object to store my values
var tempPair = new Object();
//iterate through the checkbox lists
for(var i = 1; i < SSList.length;i++)
{
//if the value is checked add it to the array
if (SSList[i].checked)
{
var P = SubAssessments[SAIndex];
var V = SSList[i].value;
//tempPair.Parent = SubAssessments[SAIndex];
tempPair.Parent = P;
//tempPair.Value = SSList[i].value;
tempPair.Value = V;
//show me the values as they exist on the page
alert(tempPair.Parent + "|" + tempPair.Value);
SubAssessmentScores.push(tempPair);
//show me the values I just added to the array
alert(SubAssessmentScores.length-1 + "|" + SubAssessmentScores[SubAssessmentScores.length-1].Parent + "|" + SubAssessmentScores[SubAssessmentScores.length-1].Value);
//uncheck the values so when I refresh that section of the page the list is empty
SSList[i].checked = false;
}
}
//output the list of objects I just created
for (i = 0;i < SubAssessmentScores.length;i++)
alert(i + "|" + SubAssessmentScores[i].Parent + "|" + SubAssessmentScores[i].Value)
Now what happens is that when I iterate through the list I get the following alerts:
-first pass-
StudentID|TestDuration
0|StudentID|TestDuration
-second pass-
StudentID|AssessmentScores
1|StudentID|AssessmentScores
This is what I expect to output... However at the end of the code snippet when it runs the for loops to spit out all the values I get the following alerts...
0|StudentID|AssessmentScores
1|StudentID|AssessmentScores
I can't for the life of me figure out why it's replacing the first value with the second value. I thought it might be using a reference variable which is why I added in the P and V variables to try to get around that if that was the case, but the results are the same.

This is because you are adding the same variable every iteration of the loop.
Try changing your push like this:
SubAssessmentScores.push({
Parent: P,
Value: V
});
That said, I recommend you study a little more javascript and conventions in the language, for example your variable naming is frowned upon because you should only use capital letters on the beginning of a name for constructor functions.
A good book is Javascript the good parts by Douglas Crockford.

Related

JavaScript Clearing Array Value

I have an array of arrays in JavaScript that I'm storing some values in, and I'm attempting to find a way to clear the value within that array when the user removes the specified control from the page, however I'm not finding a good way to do this and anything I try doesn't seem to be working.
What is the best method for clearing the value in the array? I'd prefer the value to be null so that it's skipped when I iterate over the array later on.
I've tried to do MyArray[id][subid] = '' but that still is technically a value. I've also tried to do MyArray[id][subid].length = 0 but that doesn't seem to do anything either. Trying to grab the index and splice it from the array returns a -1 and therefore doesn't work either.
var MyArray;
window.onload = function(){
MyArray = new Array();
}
function EditValuesAdd(){
var Input = document.getElementById('Values-Input').value;
var ID = document.getElementById('FID').value;
var ValueID = ControlID(); // generate GUID
if (!MyArray[ID]) MyArray[ID] = new Array();
MyArray[ID][ValueID] = Input;
document.getElementById('Values').innerHTML += '<a href="#" id="FV-' + ValueID + '" onclick="EditValuesRemove(this.id)"/><br id="V-' + ValueID + '"/>';
}
function EditValuesRemove(id)
{
var ID = document.getElementById('FID').value;
document.getElementById(id).remove();
document.getElementById(id.replace('FV-', 'V-')).remove();
MyArray[ID][id.replace('FV-', '')] = '';
}
I've also tried to do an index of and then splice it from the underlying array but the index always returns -1.
var Index = MyArray[ID].indexOf(id.replace('FV-', ''));
MyArray[ID].splice(Index, 1);
Setting the length to zero has no effect either.
MyArray[ID][id.replace('FV-', '')].length = 0;
I would expect that one of the methods above would clear out the value and make it null so that it is skipped later on but all of the methods I've found and tried so far leave some non-null value.
What you need is an object (a Map), not an array (a list).
Here's a basic idea of how to do it :
MyArray = {};
....
if (!MyArray[ID]) MyArray[ID] = {}
MyArray[ID][ValueID] = Input;
...
delete MyArray[ID][id.replace('FV-', '')];
Check here for more information : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
In the end I used an array of objects MyArray = [] and then using splice/findindex to remove it from the array:
function RemoveItem(id)
{
var Index = MyArray.findIndex(a => a.ID == id.replace('FV-', ''));
MyArray.splice(Index, 1);
document.getElementById(id).remove();
document.getElementById('FVB-' + id.replace('FV-', '')).remove();
}
It doesn't solve the actual question asked but I don't know if there really is an answer since I was using arrays in the wrong manner. Hopefully this at least points someone else in the right direction when dealing with arrays and objects.

How to merge duplicate values in a for loop javascript

I am new to js and I don't understand much of codes and conditions in js.
My question is simple but I need someone to give me a good example if possible as I know what I need but it is getting hard to implement that in code.
This is my code with 2 arrays where the data is coming from.
blind_tmp = '';
for (i=0; i<#All of Blind Relationship Link.length; i++){
blind_tmp = blind_tmp + '<p>[**' + #All of Element Title[i] + '**](' + #All of Blind Relationship Link[i] + ')'
};
What simple needed is that. I want merge records that are duplicates printed.
for example: if Blind Relationship link is AF44 and after 6 elements this AF44 comes again so I want both to be written like 1.AF44,2.AF44
while now it is writing the elements how they come along
example:
AF11,AF22,AF33,AF44,AF55,AF66,AF77,AF44
so in this example you see two AF44
I want them to be written like this
AF11,AF22,AF33,AF44AF44,AF55,AF66,AF77
any help with a code example is appreciated.
The idea is to iterate through each element in the blindRelationshipLink and store those elements in a temporary array which will be used to check the number of occurrence of an array element.
var blindRelationshipLink = ['AF11','AF22','AF33','AF11','AF44','AF44','AF55','AF66','AF77','AF11','AF22','AF11'];
var arrTemp = [];
var p = '';
blindRelationshipLink.forEach(function(arr){
var count = 0;
arrTemp.forEach(function(a){
if(arr === a)
count++;
});
arrTemp.push(arr);
if(count){
count++;
arr= arr + '.' + count;
}
p = p + arr + ',';
});
alert(p);
You test by running the code snippet.
This approach is not best but it may serve your purpose.
Here is a snippet
var elemArray = ['AF11', 'AF22', 'AF33', 'AF44', 'AF55', 'AF66', 'AF77', 'AF44']; // Array of elements
//A new array which which will contain elements which pass our case
var finalArray = [];
elemArray.forEach(function(item) { // loop through main array
// Check if element is present or else push the element
if (finalArray.indexOf(item) == -1) {
finalArray.push(item);
} else {
// if element is there find the index
var getIndex = finalArray.indexOf(item);
// remove the element, else there will be duplicate
finalArray.splice(getIndex, 1);
//concate the matched element
var newElem = item + item;
// push the element in specfic index
finalArray[getIndex] = newElem;
}
})
console.log(finalArray)
Current drawback with this code is what will happen if there are multiple repeated item in the main array. For example presence of AF33 more than twice.
DEMO

For each element in array-json object

1) What I want is to have:
element1 = [roof, walls, floor]
element2 = [table, chair]
2) My starting point is:
for(var i=0;i<roomElements;i++){
var room = [];
room.push({"element" + i + : getElement(room)});
}
"i" ruins the party. How can I append a dynamic variable to my json array?
I need room to be an object like:
var room = {"element1":"roof,walls,floor","element2":"table,chair"};
And then I want to process that object -somehow- so I can get:
element1 = [roof, walls, floor]
element2 = [table, chair]
And then I want to echo these new variables with something like.
for each element in room
So I can output:
alert("element 1 has roof, walls,floor", "element2 has table, chair")
You can't (before ES6) use dynamic field names like that.
Instead of room.push({"element" + i + : getElement(room)});, you would need:
var foo = {};
foo["element" + i] = getElement(room);
room.push(foo);
With ES6, you can use calculated property name, so
room.push({["element" + i]: getElement(room)});
becomes legal.
Because you're reinitializing elem each iteration, that still won't do exactly what you wanted. It would probably work better to take each of your starting arrays, join their elements, and create a finished object of the results:
var json = {
element1: element1.join(','),
element2: element2.join(',')
};

SQL + Javascript - Multiple fields into something I can loop through?

I have two fields I need to pull data from in SQL and put that into an array or list that I can loop through. Then for each loop, I do something based on both the fields for each index. What is the best method for this? I thought maybe a dictionary or possibly creating an object?
Right now I pull the fields into two seperate arrays, and I loop through both at the same time, but I am finding that sometimes one array has a blank value, and then they get out of sync and I have issues. This seems like a terrible implementation anyway.
How can I put these into a key value pair and then act on the data?
Edit: I should note that my SQL code just returns a bunch of comma seperated values. So it was easy to create an array out of those, but its proving more difficult to create anything else such as an object because I get all the values at one time.. :(
var equipIDArray = //SQL Gathering code here
var equipTypeArray = //SQL gathering code here
for(var cnt = 0; cnt < equipIDArray.length; cnt++){
alert(cnt);
if(isNaN(equipIDArray[cnt]) === true){
equipIDArray[cnt] = '';
}
switch(equipTypeArray[cnt]){
case 'Blower' :
alert('test1');
break;
case 'Dehumidifier' :
alert('test2');
break;
default :
alert('default');
}
}
It' easy to translate your arrays into an object if they just represent key/value pairs. Then you have an object you can use like a dictionary:
var equipIDArray = ["Blower","Humidifier","Lawn Mower"];
var equipTypeArray = ["Leaf blower","Whole House Humidifier","Honda Brand"];
var equipment = {};
for(var i = 0; i < equipIDArray.length; i++) {
equipment[equipIDArray[i]] = equipTypeArray[i];
}
for(property in equipment) {
console.log(property + " : " + equipment[property]);
alert(property + " : " + equipment[property]);
}

Is there a way to make a dynamic variable name based on the value of another variable?

Is there a way to make the value of a variable the name for another variable? For example, I want the variable name (value_of_i) to be what ever number "i" is during that iteration. The while loop below is not what I'm using it for, it's just to explain what I'm asking.
var i = 1;
while(i<10)
{
var value_of_i = "This loop has ran " + i + "times.";
i++;
}
For the first iteration, "i" is equal to 1 so I would want the variable name to be "1":
var 1 = "This loop has ran " + i + "times.";
And the second interation:
var 2 = "This loop has ran " + i + "times.";
Yes. Using bracket notation (Here is a tutorial in MDN)
Here is a working fiddle
When doing something like containingObject[stringVariable] you are accessing the property in containingObject whose name is the value stored in stringVariable.
// this assumes browser JavaScript where window is the global namespace
// in node.js this would be a little different
var i=0;
while(i<10){
window["counters"+i] = "This is loop has ran " + i + "times.";
i++;
}
console.log(counters3);
If you'd like you can use this instead of window, however this might fail in strict mode.
Here is the main explanation of how bracket notation works from the MDN link above:
Properties of JavaScript objects can also be accessed or set using a bracket notation. Objects are sometimes called associative arrays, since each property is associated with a string value that can be used to access it. So, for example, you could access the properties of the myCar object as follows:
myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;
You can also access properties by using a string value that is stored in a variable:
var propertyName = "make";
myCar[propertyName] = "Ford";
propertyName = "model";
myCar[propertyName] = "Mustang";
You can't make a variable name a number, its not a valid name. So var 1="" is invalid.
But to dynamically set the value you can do
var x = "variablenamehere";
window[x] = "variablevaluehere";
Thats the same as
var variablenamehere
except that it will be scoped as a global variable and will be accessible everywhere, rather than being limited to the current function scope.
Why not store your strings in an array that is indexed by i?
That way you can reference them later efficiently and easily;
var loopI = new Array();
for(var i = 0; i < 10; ++i) {
loopI[i] = "This loop has ran " + i + "times.";
}
This works:
var o = {};
var d = "dog";
for (var k = 0; k < 5; k += 1) {
o[d+k] = k*100;
}
console.log(o.dog3); // 300
This comes closer to doing what you want:
var N = {};
var M = {};
var i = 1;
while(i<10)
{
N[i] = "This loop ran " + i + " times.";
// Or, so you can use dot notation later:
M['OO'+i] = "This loop ran " + i + " times.";
// Those are capital O's, not zeros. Numbers won't work.
i++;
}
console.log(N[3]); // This loop ran 3 times.
console.log(M.OO7); // This loop ran 7 times.
The 'OO' notation could cause bewilderment and wasted time for others trying to use your code; but it could also be a source of amusement for them. This reminds me of a chess board after white's first two moves are to bring out a knight and then put it back. The board then seems to show that black moved first, and some people will endlessly insist that the configuration proves there was illegal play unless someone tells them what happened.

Categories