JavaScript JSON compare - javascript

There are two JSON var (JSON.parse'd already)
var acc http://pastebin.com/7DyfFzTx
var sit http://pastebin.com/vnZiVaDx
My objective is to loop each var to compare acc.items.site_name with sit.items.main_site.name to see if they are equal. If they are equal, then I need to store sit.items.main_site.site_url in a variable. I am using this code:
for(i=0; i < acc.items.length;i++)
{
aname = acc.items[i].site_name;
for(i=0; i < sit.items.length;i++)
{
sname = sit.items[i].main_site.name;
if (aname == sname)
alert("same "+aname);
}
}
But the alert only logs "same Physics" . "Physics" is the first object in acc.items. This means that the loop is only comparing first acc.items but how do I make it compare the second and further on objects (e.g. "TeX - LaTeX")

Well, you can start by using a different control variable for the outer and inner loops. :)
Also, notice how you are running through every element of the second object each time you consider an element in the first object- that doesn't seem like what you want to do.
Try reviewing this posting for a more modular method:
http://jsperf.com/recursive-vs-json-object-comparison

You're using the same variable for the inner and outer loop.
Give the second for loop a different variable name than i

Related

How to determine if an array of string objects is empty using ngIf?

I have to write a code in which I must transfer some items between two lists and hide an error when the array of object literals to be transferred to isn't empty. I have created two controllers(to manage two separate lists) and one service to deal with common data. A list has been defined inside the service along with some functions to transfer items from one list to another. The array size never seemed to change from 0,which is the logic i am trying to use in ngIf.
My logic was to check if the array is empty, then return a value of true if it was empty and set a variable empty in the controller. Then in ng-if I will check ng-if="b.empty" and thought that that would work but it didnt. The array size would remain 0 all throughout the life cycle of my code. I used ._isEmpty(list),angular([],[]) and the most obvious, array.length but the issue was initially they showed 0, but then the array size never changed. Even after populating the target array, the size seemed to stay 0 with any/all of the above functions/methods.
l1.$inject = ['listService']
function l1(listService){
var buying = this;
buying.items = listService.display();
buying.Add = function ($index){
listService.addItem($index);
}
}; //This is the controller for the source array.
.
.
.
bought.empty = listService.checkIfFull(); //Part of the second controller which assigns empty a boolean value
.
.
.
service.checkIfFull = function (){
if(blist.length == 0){
console.log(_.isEmpty(blist))
console.log(tblist)
return false;
}
else
{
console.log("not going here");
return true;
}
}; //The service checks if the array is empty
<div class="emptyMessage" ng-if="b.empty">Nothing bought</div>
The value of the console.log statements also only seem to be executing in the true portion of the if statement. I found a solution for this, which was to simply check in the html tag itself, if the local list's(that I'm looping through which ng-repeat)length was equal to zero and that worked. But could you please explain why my attempt is wrong? I am a beginner to AngularJs and JS in general so i might have not understood some rules about js and thus written wrong code. Thank you.
Edit: Here's the link to the codepen-> https://codepen.io/meanmanmachineman/pen/RmmdjY
Your problem is caused by the line bought.empty = listService.checkIfFull();. There you are calling to the function listService.checkIfFull() and assigning the returned value to bought.empty. What you should do is to assign the function itself to bought.empty:
bought.empty = listService.checkIfFull;
This way each time bought.empty is evaluated, it returns the current real value.
EDIT:
I'll try to be more explicit about the difference between, bought.empty = listService.checkIfFull() and bought.empty = listService.checkIfFull.
The first way, bought.empty will call to listService.checkIfFull() and store the returned value as a static value and any time the variable is evaluated, the value will be the same.
By using the other method, the value of bought.empty is not a number but the listService.checkIfFull function itself. This way, each time AngularJS evaluates the variable, the function is executed and returns the corresponding value.

Array reloop to remove previous set of array data generated

My file works just fine in the first round of loop when i try to rerun the function again. It shows the previous value of the previous loop when i try to use the value to match and after which it shows the correct value. If i run the function again and again, it keeps holding on to the value of the previous generated random value.
for (var i=0; i<9; i++)
{
var ranD = Math.floor(Math.random()*33);
if (mathStar.indexOf(ranD)== -1) {
mathStar.push(ranD);
item[i].innerHTML = mathStar[i];
}
else {
i--;
}
itemVal[i].value = mathStar[i];
}
Substitute using const and let for var within for loop to avoid creating global variables and --i could have unexpected results within the code where i++ is also used in the foor loop.
Is this the first occurrence of "mathStar"?
If this is the first place you're using mathStar, it means it gets created globally and that usually leads to confusion. In this case, take a look at this.
Looking at just this, it seems that you are not resetting your "mathStar" value. This way, any time you run this loop for the nth time, the values you have added to "mathStar" using mathStar.push(...) also occur in the list of values.

JavaScript For Loop Breaking Early

Why would a for loop terminate early in JavaScript? For some reason my outer for loop terminates after the first repetition. I am new to JavaScript but would expect something like this to work in Java.
function check(){
var elements = document.getElementById('fields').children;
var filteredMolecules = molecules;
console.log(elements.length);
for (i = 0; i < elements.length; i++) {
console.log(elements[i].id)
filterMolecules(filteredMolecules, elements[i].id, 0, 10);
}
}
function filterMolecules(molecules, parameter, lower, upper){
console.log('filtering');
var filteredMolecules = [];
for (i=0;i<molecules.length;i++){
var value = molecules[i].val()[parameter];
filteredMolecules.push(molecules[i]);
}
molecules=filteredMolecules;
}
In check(), I loop through elements which contains 22 items as shown by the first console.log(elements.length). If I remove the method filterMolecules(...) then all 22 IDs are logged. However, with the code as is, only the first id is logged.
I believe the filterMolecules method which should run elements.length number of times is causing the outer for loop to not work. Could someone please explain why this is happening. If relevant, in filterMolecules(...) the data is retrieved from Google Firebase with molecules[i].val()[parameter]. Additionally, both methods use the global variable molecules (line 3 and line 14)
When you don't declare variables in javascript you end up using globals (which can be a difficult to spot source of bugs). So here you are using the same global variable i for both loops. When you start looping thought molecules you are accidentally incrementing the counter loop of your first for. Use different variables or define them with :
for (let i=0;i<molecules.length;i++)
Which will give each loop its own version of i.
In this case, since the declarations are inside individual functions, you could use var too:
for (var i=0;i<molecules.length;i++) {
// etc.
}

Create array of variables from for loop (Javascript)

Let's say I have the following for loop in Javascript (this is for Adobe Photoshop using ExtendScript):
http://prntscr.com/cx2cab
Would it be possible to rewrite this so that all six of the created created text fields are all assigned as six different variables, each with a constant name only differing by "i" as specified in the for loop? Furthermore, would it then be possible to assign all of those variables into an array within the for loop instead of writing out each variable name in the array individually? If so, how would you go about this?
You can create window variables window["num"] = "1" == var num = "1"
var p = ["I","You","We","They"];
for(var i=0;i<p.length;i++){
window[p[i]] = p[i]+" "+"Love Cacke";
}
//now you have variables I,You,We,They
console.log(I);
console.log(You);
console.log(We);
console.log(They);
/*
[
"I Love Cacke",
"You Love Cacke",
"We Love Cacke",
"They Love Cacke"
]
*/

Using Javascript to automatically generate multiple html elements of the same type based on a 2 dimentional array of attributes causes browser to hang

I've created 2 functions for creating DOM elements. The first builds a single element node, inserts attributes based on an array of attribute/value pairs, inserts a text node and puts the element into a parent. This function works fine except when the second function calls it.
The second calls the first function to generate multiple elements of the same type and parent but with different text and attributes (for generating things such as li, option, or p elements). This function's parameters are the type of element to create repeatedly, the parent element to be added to, an array of arrays each containing attribute value pairs, and an array of strings for use in the text node (array of arrays and array of strings must be the same length). The number of elements created is based on the number of attribute arrays.
The problem is that when the 2nd function calls the 1st it seems to hang the browser.
Help and or advice would be much appreciated.
The code I've been running:
function buildElement(type, txt, attr, parent){
element = document.createElement(type);
if(typeof attr != 'undefined' && attr){
for(i=0; i<attr.length; i=i+2){
element.setAttribute(attr[i], attr[i+1]);
}
}
if(typeof txt != 'undefined' && txt){
element.appendChild(document.createTextNode(txt));
}
if(typeof parent != 'undefined' && parent){
parent.appendChild(element);
}
return element;
}
function multiElements(type, parent, attrs, txts){
for(i=0; i<attrs.length; i++){
buildElement(type,txts[i],attrs[i],parent);
}
}
var x=1;
var local = buildElement('select','','name','local'+x,'onchange',
'selectPhUpdate(this.value)'],newCard);
multiElements('option',
local,
[
['value','auck'],
['value','chch'],
['value','dun'],
['value','ham'],
['value','mor'],
['value','nap'],
['value','nply'],
['value','wel']
],
['Auckland','Christchurch','Dunedin','Hamilton','Morrinsville',
'Napier','New Plymouth','Wellington']
);
First of all, there is a [ missing in your code,
var local = buildElement('select','','name','local'+x,'onchange',
'selectPhUpdate(this.value)'],newCard);
should be
var local = buildElement('select','',['name','local'+x,'onchange',
'selectPhUpdate(this.value)'],newCard);
As for the problem itself: You are using global variables for everything, even for your loop counter – and you used i for the loop counter both times.
You have two entries each on the second level of your attrs array that you pass from multiElements to buildElement, so i always has a value of 2 when the loop over the current 2nd level array in buildElement is finished – and that means, the loop in multiElements never stops, because 2 is always lesser than attrs.length (which is 8) … and so the third option for “Dunedin” gets created over and over and over … and over … again.
As soon as you use for(var i=0; … for both of your loops, thereby making each i a local variable within the scope of the respective function, it works as expected.
(element in buildElement should be made local, too.)
See it working with those small fixes in this fiddle: http://jsfiddle.net/c7Pq3/1/

Categories

Resources