JQuery for loop - javascript

I need to Loop in JQuery from 0 to variable-value(dynamically entered by user).How can i achieve this?
Now i am doing it by using simple For loop like this.
for( i=1; i<=fetch; i++) {
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
}
Thanks.

You could loop an empty array:
$.each(new Array(fetch), function(i) {
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
});
If you do this alot you can even fake-patch jQuery.each to take numbers:
(function($) {
var _each = $.each;
$.each = function() {
var args = $.makeArray(arguments);
if ( args.length == 2 && typeof args[0] == 'number') {
return _each.call(this, new Array(args[0]), args[1]);
}
return _each.call(this, args);
};
}(jQuery));​
$.each(fetch, function(i) {
// loop
});
jQuery.each does have some great features, like the different return values inside the callback. But for a simple loop I find it much more convenient (and less overhead) to do something like:
while(fetch--) {
// loop
}​

To loop between two values you should use a regular Javascript loop. The jQuery each methods are used when looping through a collection of elements or an array.
To loop from zero, you should initialise the loop variable to zero, not one. To loop from zero to the specified value, you use the <= for the comparison, but to loop from zero and the number of items as specified (i.e. from 0 to value-1), you use the < operator.
for (i = 0; i < fetch; i++) {
$('body').append($('<input/>', { type: 'text' }));
}

You mean Javascript loop.
From W3Schools:
for (var variable = startvalue; variable < endvalue; variable = variable + increment)
{
//code to be executed
}

To get the value from user and run the code you can use the following prompt.
var x=prompt("Enter the value",0);
for(i=0;i<x;i++)
{
var dyndivtext = document.createElement("input");
document.body.appendChild(dyndivtext);
}
Hope this helps.
Thanks

If you want it the full jQuery way then use that new plugin jQuery-timing. It provides inline-loops in your jQuery line:
$('body').repeat().append('<input>').until(fetch);
Nice, eh?

Related

Counter array in Javascript

I am trying to make two arrays. the unique array can get the elements (no repeats) from the text array, and the counter one can count the frequency of each elements. but something is wrong with the counter one.
var unique_array=new Array();
var counter_array=new Array();
var unique=true;
for (i=0;i<text_array.length;i++){
if (unique_array.length==0){
unique_array.push(text_array[0]);
counter_array.push(1);
}
else if(unique_array.length>0&&unique_array.length<=text_array.length){
for (j=0; j<unique_array.length;j++){
if (text_array[i]==unique_array[j]){
counter_array[j]=counter_array[j]+1;// something wrong with the
alert(counter_array[j]);
var unique=false;
}
}
if (unique==true){
unique_array.push(text_array[i]);
counter_array.push[1];
}
unique=true;
}
You could also simplify the code down using a hashmap and some ES5 higher-order functions:
var text_array = ["a1","a1","a2","a3","a2","a4","a1","a5"];
var counts = {};
text_array.forEach(function(el) {
counts[el] = counts.hasOwnProperty(el) ? counts[el]+1 : 1;
});
var unique_array = Object.keys(counts);
var counter_array=unique_array.map(function(key) { return counts[key]; })
You can do this much more simply using an object. Let the values be the keys of an object, then just increment the count of each property as you go. At the end, you can get an array of the unique keys and their values:
var text_array = ['foo','bar','foo','fum','fum','foo'];
var i = text_array.length;
var obj = {};
while (i--) {
if (obj.hasOwnProperty(text_array[i])) {
obj[text_array[i]]++;
} else {
obj[text_array[i]] = 1;
}
}
console.log('Unique values: ' + Object.keys(obj)); // Unique values: foo,fum,bar
console.log('Value counts: ' + Object.keys(obj).map(function(v){return obj[v]})); // Value counts: 3,2,1
Note that the sorting of counts in the output is purely coincidental.
As Jasvir posted, you can make it pretty concise:
var obj = {};
text_array.forEach(function(v) {
obj.hasOwnProperty(v)? ++obj[v] : obj[v] = 1;
});
But the first example is a bit easier to digest.
I think the approach is what's making it difficult. A hash table / associative array would be much easier to work with.
With a hash table (an object {} in JS), you can store each word in a key and increment the value of the key when you encounter the word again. Then, at the end, just go through the hash table and gather up all the keys which have small values. Those are your unique words.
function get_unique_words(text_array) {
var hash_table, i, unique_words, keys;
hash_table = {};
for(i = 0; i < text_array.length; i++) {
if(hash_table[text_array[i]] === undefined) {
hash_table[text_array[i]] = 1;
} else {
hash_table[text_array[i]]++;
}
}
// go through the hash table and get all the unique words
unique_words = [];
keys = Object.keys(hash_table);
for(i = 0; i < keys.length; i++) {
if(hash_table[keys[i]] === 1) {
unique_words.push(keys[i]);
}
}
return unique_words.sort();
}
console.log(get_unique_words(
['blah', 'blah', 'blah', 'goose', 'duck',
'mountain', 'rock', 'paper', 'rock', 'scissors']
));
Some issues and suggestions :
Don't use var twice for the same variable.
Browsers deal with it ok, but for clarity you should only be declaring your variables once.
Always localize your loop counters - forgetting a var before your i and j will cause them to become global variables.
This is relevant when you have a page with lots of code - all global variables will show up in the debugger's watch list at all times, making it harder to debug your code.)
Use the array literal notation [] instead of the function form Array.
The function form is longer and it's easier to forget the new. It's also easier to read (IMO).
Use more whitespace (it won't bite), such as before and after an equals sign:
var x = 1;
// vs.
var x=1;
It makes the code easier to read and most people don't overdo it.
Indent your code when it's inside a block (e.g. function, if, else, while, for, etc.).
This makes it easier to read the control flow of the code and will help prevent bugs.
Use three equals signs (===) unless you are using loose equality on purpose.
This will help someone looking at your code later (probably yourself) understand better what the test is supposed to be testing.

Can I select 2nd element of a 2 dimensional array by value of the first element in Javascript?

I have a JSON response like this:
var errorLog = "[[\"comp\",\"Please add company name!\"],
[\"zip\",\"Please add zip code!\"],
...
Which I'm deserializing like this:
var log = jQuery.parseJSON(errorLog);
Now I can access elements like this:
log[1][1] > "Please add company name"
Question:
If I have the first value comp, is there a way to directly get the 2nd value by doing:
log[comp][1]
without looping through the whole array.
Thanks for help!
No. Unless the 'value' of the first array (maybe I should say, the first dimension, or the first row), is also it's key. That is, unless it is something like this:
log = {
'comp': 'Please add a company name'
.
.
.
}
Now, log['comp'] or log.comp is legal.
There are two was to do this, but neither avoids a loop. The first is to loop through the array each time you access the items:
var val = '';
for (var i = 0; i < errorLog.length; i++) {
if (errorLog[i][0] === "comp") {
val = errorLog[i][1];
break;
}
}
The other would be to work your array into an object and access it with object notation.
var errors = {};
for (var i = 0; i < errorLog.length; i++) {
errors[errorLog[i][0]] = errorLog[i][1];
}
You could then access the relevant value with errors.comp.
If you're only looking once, the first option is probably better. If you may look more than once, it's probably best to use the second system since (a) you only need to do the loop once, which is more efficient, (b) you don't repeat yourself with the looping code, (c) it's immediately obvious what you're trying to do.
No matter what you are going to loop through the array somehow even it is obscured for you a bit by tools like jQuery.
You could create an object from the array as has been suggested like this:
var objLookup = function(arr, search) {
var o = {}, i, l, first, second;
for (i=0, l=arr.length; i<l; i++) {
first = arr[i][0]; // These variables are for convenience and readability.
second = arr[i][1]; // The function could be rewritten without them.
o[first] = second;
}
return o[search];
}
But the faster solution would be to just loop through the array and return the value as soon as it is found:
var indexLookup = function(arr, search){
var index = -1, i, l;
for (i = 0, l = arr.length; i<l; i++) {
if (arr[i][0] === search) return arr[i][1];
}
return undefined;
}
You could then just use these functions like this in your code so that you don't have to have the looping in the middle of all your code:
var log = [
["comp","Please add company name!"],
["zip","Please add zip code!"]
];
objLookup(log, "zip"); // Please add zip code!
indexLookup(log, "comp"); // Please add company name!
Here is a jsfiddle that shows these in use.
Have you looked at jQuery's grep or inArray method?
See this discussion
Are there any jquery features to query multi-dimensional arrays in a similar fashion to the DOM?

jquery for loop issue

i have a below function through which i am trying to append something. it internally calls another function which does the append function..
function something()
for(var i=0; i <= obj.result.length; i++) {
EDIT
obj = objEval.result[i].uniquename;
prop = objEval.result[i].prop;
count = objEval.result[i].count;
// count is 21 in my case. below function is called..
if (count > 0){
callAdd(obj,prop);
}
}
}
actual function that does the appending
function callAdd(obj,prop){
// obj exists in DOM.. checked via $(obj).length -- greater than 0
$(obj).append(prop);
}
issue here is, even if the append function is in for loop.. only the first element is being sent to the callAdd function.. as below:
i have 4 obj, props:
obj=45183371 and prop=6
obj=560488951 and prop=12
obj=616516330 and prop=23
obj=915329019 and prop=5
but only the first pair (obj=45183371 and prop=6) is being sent to the callAdd function as params..
pls help..
something() generally needs to be added a param, other-wise how would it function? where would it build its loop? Global var? I dont see one
Try this.
Get all objs in an Array.
var objAry=new Array();
Get all props in an Array.
var propsAry=new Array();
Now
function something()
{
var propsAry=new Array();
var objAry=new Array();
objAry= //Your objs
propsAry=//Your props
for(var i=0; i <= objAry. length; i++)
{
if (count > 0)
{
callAdd(objAry[i], propsAry[i]);
}
}
}
You are changing the variable you're depending on (obj) to limit your loop control variable (i). When you re-assign obj inside the body of the loop:
obj = objEval.result[i].uniquename;
The looping condition:
i <= obj.result.length
Will be false on the next iteration. Inside the body of the loop, create a new variable instead of assigning something new to obj.
Alternatively (or additionally), cache the number of iterations you want in a variable instead:
var len = obj.result.length;
for (var i = 0; i <= len; i++) {
// Do whatever you want to obj.
}
You dont have count defined so use i:
if (i > 0){
callAdd(obj,prop);
};

Code doesn't work in foreach

Here is my code:
var divarray = document.getElementById("yui-main").getElementsByTagName("div");
var articleHTML;
var absHTML;
var keyHTML;
var bodyHTML = [];
for( var i in divarray) {
if(divarray[i].className == "articleBody"){
articleHTML = divarray[i];
for( var j in articleHTML ){
bodyHTML[i] = '';
if(articleHTML[j].className == "issueMiniFeature"){continue;}
if(articleHTML[j].className == "abstract"){absHTML = articleHTML[i]; continue;}
if(articleHTML[j].className == "journalKeywords"){keyHTML = articleHTML[i]; continue;}
bodyHTML[i] = articleHTML[i];
}
break;
}
i++;
}
The error I am getting is:
SyntaxError: Unexpected token var
I am using Google Chrome
The javascript for...in doesn't do what you would expect (which is enumerate through eleemnts in an array.
for...in in javascript will enumerate through the key/value pairs (or public variables) that make up the object (which isn't what you want).
You need to use a good, old fashioned for loop.
You can add this to your script:
Array.prototype.foreach = function (callback) {
for (var i=0; i < this.length; i++) {
callback(this[i]);
}
}
Then you simply do this:
myarray.foreach(function (currentItem) {
/*...do whatever with the currentItem...*/
});
I think you mistaking JavaScript for the functionality of PHP. JavaScript does not have foreach loops. JavaScript has for in, which is what you are incorrectly using and normal for loops. Use a standard for loop when dealing with arrays. You will need to use a for in loop with object literals because the index is not the simplicity of an incrementing positive integer.
In JavaScript a for loop has 3 parts in its argument separated by a semicolon as follows:
* start position of incrementor (optional if the variable is previous defined with 0 or a positive integer)
* end position of incrementor
* method of incrementation
In the following examples arrayName is value I made up for the name of an array:
for (; a < arrayName.length; a += 1) {
for (a = x + 1; a < arrayName.length + 3; a += 2) {
The for in loop argument has two required parts and a third part to prevent errors using an if condition:
* The value of an index to search for
* The name of the container in which to search
* The third part is an if condition
The following example will return the value supplied to the "book" index of the objectName object literal. objectName is a name I made for an example object literal:
for ("book" in objectName) {
if (objectName.hasProperty("book")) {
Why not use a traditional for loop instead? You're not really using an associative array here ...
That's not the right way to iterate over a collection.
You want a standard for loop, not a for..in loop
for( var i = 0, l = divarray.length; i < l; i++ ) {
There's something else, you then proceed to try to iterate over each element
for( var j in articleHTML ){
articleHTML at this point holds a reference to a single HTML node - not a collection or array of any sort.

Replacing jQuery each with for

I've been using $.each to do iterations for a while now, but I keep on hearing people say to use native JS for to do loops. I'm very concerned about performance but I am not sure if it's always possible to replace $.each with for in a meaningful way.
So my questions are, is it possible to always replace $.each with for, and if not what's the rule of thumb for when it can be done and when it cannot.
I have an each like this:
$this.find("div.class").each(function (){
var $thisparent = $(this).parent();
if (condition) {
$(this).prepend($thisparent.text());
}
if (condition2) {
$(this).prepend($thisparent.text());
}
});
This is what jQuery does with .each, basically:
$.fn.each = function(callback) {
var i, length = this.length;
for(i = 0; i < length; ++i) {
callback.call(this[i]);
}
};
So it's not hard to substitute your anonymous function's 'contents' with the callback.call call. Just be sure to replace this with a temporary with the jQuery object.
Converting your supplied code:
var foo = $this.find("div.class"),
fooLength = foo.length,
i,
$thisparent;
for (i = 0; i < fooLength; ++i) {
$thisparent = $(foo[i]).parent();
if (condition) {
$(foo[i]).prepend($thisparent.text());
}
if (condition2) {
$(foo[i]).prepend($thisparent.text());
}
}
For additional (potential) speed, cache foo[i] into a temporary. too, and assign $thisparent only when needed. If condition and condition2 are mutually exclusive, use a single if (condition || condition2).
Someone compared the performance of for and $.each:
http://jquery-howto.blogspot.com/2009/06/javascript-for-loop-vs-jquery-each.html

Categories