won't loop array javascript - javascript

Why cant i access my array?
function map(array){
for(i=0; i <=array.length; i++){
var location=array[i].location;
console.log("loc"+location);
var user = array[i].from_user;
console.log("user"+user);
var date = array[i].created_at;
var profile_img = array[i].profile_img;
var text = array[i].text;
var contentString = text;
//geocode(user,date, profile_img, text, contentString,location);
}
}
It gives me undefined for every element.I want to access it and pass the variables to the geocode function.
data structure:
array=[{user: a,user_id: b,date: c,profile_img: d,text: e,contentString: f,url:
g,location:o},{user: a,user_id: b,date: c,profile_img: d,text: e,contentString:
f,url:g,location:o},{user: a,user_id: b,date: c,profile_img: d,text:
e,contentString: f,url: g,location:s}];
dont worry about the values..!
I forgot to mention when i first made the post(question). the location of the array is inserted in the previous function whereas the array didn't include the attribute location from previous functions

When calling the function, use the object literal construct enclosed in an array literal, otherwise all values will be returned as undefined. This is how you should call your function:
map([{ // array literal enclosing an object literal
location : 1,
from_user : 2,
created_at : 3,
profile_img: 4,
text : 5
}]);
Moreover, in your loop, change:
for (i = 0; i <= array.length; i++ ) ...
...to
for (var i = 0; i < array.length; i++) ...
If you have a pre-defined array, name it and pass it to the function like this:
map(arrayObj)

If the array you pass in has a length of 0, the way you're looping it is going to try and access the list element at 0, which is going to be undefined.
However, regardless of the contents of your array, this line will always cause you trouble:
for(i=0; i <=array.length; i++)
When check the length property of your array, it is telling you the number of elements in the array. Since arrays use 0 based indexing, you're going to overrun the bounds of your array with this loop everytime.
var myArray = [1, 2, 3];
myArrary[0]; // This is 1
myArray[2]; // This is 3
Since you are looping between 0 and the length of the array, which happens to be 3, the last element you attempt to access will no exist.
myArray[3]; // Undefined
You need to check i < array.length rather than i <= array.length.

Your code is fine. With the provided input and function you get this:
loco
userundefined
loco
userundefined
locs
userundefined
The reason every user is coming up as undefined is because of:
var user = array[i].from_user;
console.log("user"+user);
The objects you are passing in do not have a from_user property, so naturally it comes up as undefined. Maybe you meant array[i].user_id?
Also, as Aesthete pointed out, you're running outside the bounds of your array because of the way you're checking for length. Do this instead:
for(var i = 0, n = array.length; i < n; i++) {
// your code in here
}
Notice that I preface i with var so it does not become an implicit global. Also, I declare a second variable n so that you only need to access array.length once. This is common practice.
So, putting it all together:
function map(array){
for(var i = 0, n = array.length; i < n; i++){
var location=array[i].location;
console.log("loc"+location);
var user = array[i].user_id;
console.log("user"+user);
var date = array[i].created_at;
var profile_img = array[i].profile_img;
var text = array[i].text;
var contentString = text;
//geocode(user,date, profile_img, text, contentString,location);
}
}
array=[{user: 'a',user_id: 'b',date: 'c',profile_img: 'd',text: 'e',contentString: 'f',url:
'g',location:'o'},{user: 'a',user_id: 'b',date: 'c',profile_img: 'd',text: 'e',contentString:
'f',url:'g',location:'o'},{user: 'a',user_id: 'b',date: 'c',profile_img: 'd',text:
'e',contentString: 'f',url: 'g',location:'s'}];
map(array);
Notice I changed your object properties to strings - this is because you did not give values for these, but you probably don't want to do this. Output is:
loco
userb
loco
userb
locs
userb
All is well. If you are still getting undefined for location then your error must lie with the o property of the objects you're passing in.

Related

Can I assign an array value to a variable?

I can't seem to assign an array value to a variable. It always returns undefined.
In my code I have set currentWord = text[wordPos]. At the end of the code I have console logged currentWord, and text[wordPos]. My thinking says that they should return the same value, but they don't. currentWord returns undefined, and text[wordPos] returns the correct value (the first word in the 'text' array).
Solved. I had mistakenly forgot that I had 2 arrays, and thought the text array was not empty, but it was. The words array is the array I had filled in separate file.
var text = Array();
var wordPos = 0;
var currentWord = text[wordPos];
function gen() {
text = [];
var random;
for (var i = 0; i < 10; i++) {
random = words[Math.floor(Math.random() * 50)];
text.push(random);
}
document.getElementById('text').innerHTML = text.join(" ");
console.log(currentWord);
console.log(text[wordPos]);
}
Currentwork is undefined because you create an array object but never push a value into it. It transfers the current value of the variable not the reference.
There is no value at index 0 of text. If you assign some values to the text array you should be good!
Updated:
Read the OP's note above about the two arrays in the original example. In light of this information, the following script simulates an imported array words of 50 distinct values in order to generate a text of ten space-delimited numbers and indicate its first value:
// simulating an array imported from a separate file
var words = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50];
function gen() {
var wordPos = 0;
var currentWord = "";
var arr = [];
var randomVal;
var d = document;
d.g = d.getElementById;
var pText = d.g('text');
// get each of 10 values by randomly selecting an element's key
for (var i = 0; i < 10; i++) {
randomVal = words[ Math.floor( Math.random() * 50 ) ];
arr.push( randomVal );
}
pText.innerHTML = arr.join(" ");
currentWord = arr[wordPos];
console.log("Current word: ",currentWord );
}
gen();
<p id="text"></p>
This script randomly selects 10 numbers and adds them to an empty array by means of variable randomVal. This variable acquires a value in each iteration of the for-loop, during which the variable is passed to the push() method of arr in order to append it to the array. Once the loop terminates, the script joins the elements of arr on a blank space character, which yields a string whose numeric values are space-delimited.
One can discern that the script is working correctly when the console.log statement displays the first numeric value appearing in the text.

JavaScript Array.shift not working

I have been programming a system that is supposed to delete the first index of an array. Instead of changing an array from (i.e) "1,2,3,4,5" to "2,3,4,5" the console gives an error: "Uncaught TypeError: num.splice is not a function". I have heard that num.splice is not a function, it is an operation (or something) to delete the first indexed value of the array. I am confused that when I use an example code from w3Schools, there is no outputted error in the console. I don't understand why this happens.
(I have given the entire code just in case it has to do with syntax issues)
function dCrypt() {
var num = document.getElementById("demoin").value; // ex: a127
var key = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var mod = 0;
var out = 0;
var prep = 0;
var pre = 0;
num.split("");
mod = num[0];
pre = key.indexOf(mod);
num.splice(0,1);
for (i=0;i <= pre;i++) {
prep += 26;
}
out = Math.floor(num + pre);
document.getElementById("demoout").innerHTML = out;
}
Thanks in advance!
When you split 'num' you have to reassign it
num = num.split("");
Referring to your link from w3schools:
The splice() method adds/removes items to/from an array, and returns the removed item(s).
As you can see the var num is string(and not an array) and has the value of the element with id demoin.
Since you are trying to splice a string and not an array. The error shows up in the console.
Solution:
Either store the value of your split in an array(it could be num itself) and then splice that array.
num = num.split("");
...
num.splice(0,1);

JavaScript stop referencing object after pass it to a function

I know JavaScript passes Objects by reference and thus I'm having a lot of trouble with the following code:
function doGradeAssignmentContent(dtos) {
var x = 5;
var allPages = [];
var stage = new App.UI.PopUpDisplay.PopUpStageAssignmentGrader(null, that);// pass launch element
for(var i = 0; i < dtos[0].result.students.length; ++i) {
var pagesSet = [];
for(var j = 0; j < dtos[0].result.questions.length; ++j) {
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
if(dtos[0].result.students[i].answers[j].assignmentQuestionId === questionObject.questionId) {// expected, if not here something is wrong
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
questionObject.pointsReceived = dtos[0].result.students[i].answers[j].pointsReceived;
} else {
var theAnswer = findAssociatedStudentAnswer(questionObject.questionId, dtos[0].result.students[i].answers[j]);
if(theAnswer !== null) {
questionObject.answer = theAnswer.studentAnswer;
questionObject.pointsReceived = theAnswer.pointsReceived;
} else {
alert("Unexpected error. Please refresh and try again.");
}
}
pagesSet[pagesSet.length] = new App.UI.PopUpDisplay.StageAssignmentGradingPages[dtos[0].result.questions[j].questionType.charAt(0).toUpperCase() + dtos[0].result.questions[j].questionType.slice(1) + "QuestionAssignmentGradingPage"](j + 1, questionObject);
}
var studentInfo = {};
studentInfo.avatar = dtos[0].result.students[i].avatar;
studentInfo.displayName = dtos[0].result.students[i].displayName;
stage.addPageSet(pagesSet, studentInfo);
}
stage.launch();
}
First let me show you what the result (dtos) looks like so you can better understand how this function is parsing it:
The result (dtos) is an Object and looks something like:
dtos Array
dtos[0], static always here
dtos[0].result, static always here
dtos[0].questions Array
dtos[0].questions.index0 - indexN. This describes our Questions, each one is an Object
dtos[0].students Array
dtos[0].students[0]-[n].answers Array. Each student array/Object has an Answers array. Each student will have as many elements in this answers Array that there were questions in dtos[0].questions. Each element is an Object
Now what we do in this here is create this Object stage. Important things here are it has an array called "this.studentsPages". This array will ultimately have as many entries as there were students in dtos[0].students.
So we loop through this for loop disecting the dtos array and creating a pagesSet array. Here comes my problem. On the first iteration through the for loop I create this questionObject element. I also have tried just doing var questionObject = {}, but what you see now was just an attempt to fix the problem I was seeing, but it didn't work either.
So at the end of the first iteration of the outer for loop I call stage.addPageSet, this is what happens here:
var pageObject = [];
pageObject["questions"] = pageSet;
pageObject["displayName"] = studentInfo.displayName;
this.studentsPages[this.studentsPages.length] = pageObject;
if(this.studentsPages.length === 1) {// first time only
for(var i = 0; i < pageSet.length; ++i) {
this.addPage(pageSet[i]);
}
}
The important thing to take notice of here is where I add pageObject on to this.studentsPages which was an empty array before the first call. pageObject now has pageSet plus a little bit more information. Remember, pageSet was an Object and thus passed by reference.
On the next iteration of the for loop, when I hit this line:
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
It goes wrong. This changes the local copy of questionObject, BUT it also changes the copy of questionObjec that was passed to addPageSet and added to the studentsPages array in the first iteration. So, if I only had 2 students coming in, then when all is said and done, studentsPages hold 2 identical Objects. This should not be true.
The problem is questionObject in the doGradeAssignmentContent function is keeping a reference to the Object created on the previous iteration and then overrides it on all subsequent iterations.
What can I do to fix this?
Thanks for the help!
With out having looked at it too closely I believe you need to change the following:
// Before:
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
// After:
var questionObject = jQuery.extend(true, {}, dtos[0].result.questions[j]);
I didn't look too closely if there are other instances in the code where this needs to be applied, but the core concept is to utilize jQuery's deep copy to generate a duplicate of the object you do not wish to retain a reference to.

Javascript - clearing duplicates from an array object

Hi
I have a javascript array object rapresenting the amount of items sold in a given country, like this:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item2', 'c3':110}]
I need to avoid duplicates (as you may see, the last two 'records' have the same Country and the same Item) and sum the amounts; if I was getting data from a database I would use the DISTINCT SUM clause, but what about it in this scenario? Is there any good jquery trick?
You could use an object as a map of distinct values, like this:
var distincts, index, sum, entry, key;
distincts = {};
sum = 0;
for (index = 0; index < data.length; ++index) {
entry = data[index];
key = entry.c1 + "--sep--" + entry.c2;
if (!distincts[key]) {
distincts[key] = true;
sum += entry.c3;
}
}
How that works: JavaScript objects are maps, and since access to properties is an extremely common operation, a decent JavaScript implementation tries to make property access quite fast (by using hashing on property keys, that sort of thing). You can access object properties using a string for their name, by using brackets ([]), so obj.foo and obj["foo"] both refer to the foo property of obj.
And so:
We start with an object with no properties.
As we loop through the array, we create unique key from c1 and c2. It's important that the "--sep--" string be something that cannot appear in c1 or c2. If case isn't significant, you might throw a .toLowerCase in there.
If distincts already has a value for that key, we know we've seen it before and we can ignore it; otherwise, we add a value (true in this case, but it can be just about anything other than false, undefined, 0, or "") as a flag indicating we've seen this unique combination before. And we add c3 to the sum.
But as someone pointed out, your last two entries aren't actually the same; I'm guessing that was just a typo in the question...
jQuery may have an array function for this, but because your two Italy objects are not distinctly unique, your asking for a custom solution. You want to populate a array and check it for duplicates as you go:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item1', 'c3':110}]
var newArray = [];
var dupeCheck = {}; // hash map
for(var i=0; i < data.length; i++){
if(!dupeCheck[data[i].c1]){
newArray.push(data[i]);
dupeCheck[data[i].c1] = true;
}
}
test
HTML:
<div id="test"></div>
JS:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item1', 'c3':110}];
var
l = data.length, // length
f = "", // find
ix = "", // index
d = []; // delete
for (var i = 0; i < l; i++) {
ix = data[i].c1 + "_" + data[i].c2 + "__";
//var re = new RegExp(ix);
//if (re.test(f))
if (f.indexOf(ix) != -1)
d.push(i);
else
f += ix;
}
for (var i1 = 0; i1 < d.length; i1++){
$("#test").append("<div>for delete: "+d[i1]+"</div>");
}
EDIT
Although chrome works much faster, works only in chrome faster the example with indexOf, then in IE/Opera/Firefox/Safary works faster with an object.
The code created by "# TJ Crowder" is much more efficient.

Javascript dynamic array of strings

Is there a way to create a dynamic array of strings on Javascript?
What I mean is, on a page the user can enter one number or thirty numbers, then he/she presses the OK button and the next page shows the array in the same order as it was entered, one element at a time.
Code is appreciated.
What I mean is, on a page the user can enter one number or thirty numbers, then he/she presses the OK button and the next page shows the array in the same order as it was entered, one element at a time.
Ok, so you need some user input first? There's a couple of methods of how to do that.
First is the prompt() function which displays a popup asking the user for some input.
Pros: easy. Cons: ugly, can't go back to edit easily.
Second is using html <input type="text"> fields.
Pros: can be styled, user can easily review and edit. Cons: a bit more coding needed.
For the prompt method, collecting your strings is a doddle:
var input = []; // initialise an empty array
var temp = '';
do {
temp = prompt("Enter a number. Press cancel or leave empty to finish.");
if (temp === "" || temp === null) {
break;
} else {
input.push(temp); // the array will dynamically grow
}
} while (1);
(Yeah it's not the prettiest loop, but it's late and I'm tired....)
The other method requires a bit more effort.
Put a single input field on the page.
Add an onfocus handler to it.
Check if there is another input element after this one, and if there is, check if it's empty.
If there is, don't do anything.
Otherwise, create a new input, put it after this one and apply the same handler to the new input.
When the user clicks OK, loop through all the <input>s on the page and store them into an array.
eg:
// if you put your dynamic text fields in a container it'll be easier to get them
var inputs = document.getElementById('inputArea').getElementsByTagName('input');
var input = [];
for (var i = 0, l = inputs.length; i < l; ++i) {
if (inputs[i].value.length) {
input.push(inputs[i].value);
}
}
After that, regardless of your method of collecting the input, you can print the numbers back on screen in a number of ways. A simple way would be like this:
var div = document.createElement('div');
for (var i = 0, l = input.length; i < l; ++i) {
div.innerHTML += input[i] + "<br />";
}
document.body.appendChild(div);
I've put this together so you can see it work at jsbin
Prompt method: http://jsbin.com/amefu
Inputs method: http://jsbin.com/iyoge
var junk=new Array();
junk.push('This is a string.');
Et cetera.
As far as I know, Javascript has dynamic arrays. You can add,delete and modify the elements on the fly.
var myArray = [1,2,3,4,5,6,7,8,9,10];
myArray.push(11);
document.writeln(myArray); // Gives 1,2,3,4,5,6,7,8,9,10,11
var myArray = [1,2,3,4,5,6,7,8,9,10];
var popped = myArray.pop();
document.writeln(myArray); // Gives 1,2,3,4,5,6,7,8,9
You can even add elements like
var myArray = new Array()
myArray[0] = 10
myArray[1] = 20
myArray[2] = 30
you can even change the values
myArray[2] = 40
Printing Order
If you want in the same order, this would suffice. Javascript prints the values in the order of key values. If you have inserted values in the array in monotonically increasing key values, then they will be printed in the same way unless you want to change the order.
Page Submission
If you are using JavaScript you don't even need to submit the values to the different page. You can even show the data on the same page by manipulating the DOM.
You can go with inserting data push, this is going to be doing in order
var arr = Array();
function arrAdd(value){
arr.push(value);
}
Here is an example. You enter a number (or whatever) in the textbox and press "add" to put it in the array. Then you press "show" to show the array items as elements.
<script type="text/javascript">
var arr = [];
function add() {
var inp = document.getElementById('num');
arr.push(inp.value);
inp.value = '';
}
function show() {
var html = '';
for (var i=0; i<arr.length; i++) {
html += '<div>' + arr[i] + '</div>';
}
var con = document.getElementById('container');
con.innerHTML = html;
}
</script>
<input type="text" id="num" />
<input type="button" onclick="add();" value="add" />
<br />
<input type="button" onclick="show();" value="show" />
<div id="container"></div>
The following code creates an Array object called myCars:
var myCars=new Array();
There are two ways of adding values to an array (you can add as many values as you need to define as many variables you require).
1:
var myCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
You could also pass an integer argument to control the array's size:
var myCars=new Array(3);
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
2:
var myCars=new Array("Saab","Volvo","BMW");
Note: If you specify numbers or true/false values inside the array then the type of variables will be numeric or Boolean instead of string.
Access an Array
You can refer to a particular element in an array by referring to the name of the array and the index number. The index number starts at 0.
The following code line:
document.write(myCars[0]);
will result in the following output:
Saab
Modify Values in an Array
To modify a value in an existing array, just add a new value to the array with a specified index number:
myCars[0]="Opel";
Now, the following code line:
document.write(myCars[0]);
will result in the following output:
Opel
Please check http://jsfiddle.net/GEBrW/ for live test.
You can use similar method for dynamic arrays creation.
var i = 0;
var a = new Array();
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
a[i++] = i;
The result:
a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5
a[5] = 6
a[6] = 7
a[7] = 8
Just initialize an array and push the element on the array.
It will automatic scale the array.
var a = [ ];
a.push('Some string'); console.log(a); // ['Some string']
a.push('another string'); console.log(a); // ['Some string', 'another string']
a.push('Some string'); console.log(a); // ['Some string', 'another string', 'Some string']

Categories

Resources