On looping through Arguments variable - javascript

So I'm learning how to code. Well, my name is Richard and I'm learning how to code on my own, with Javascript. While I have been putting some amount of work into this consistantly during a few months, only finally I have had the means to practice on an environment where code can actually be run (before this I would put vertical lines on a notebook as indentations and practice there), and in the book I'm using as a guide (which is very good by the way, or so I feel), I found an exercise which requires to build a function which makes an array taking parameters to start and finish the array as well as a step to count that can be obviated and treated as 1 by the function (done), and then a second function that can take the values in that array and sum them, then return the result (done as well). That one was a little bit tricky while I figured out how to work with the arguments variable, but then I started thinking on how I could improve this last function, and add more functionality to it. To both really.
The step I'm stuck on is that one. I'm trying to enhance both variables to go beyond working with ONE array at a time. Instead, I want the Range function to be able to take multiple different parameters (arrays of numbers or just numbers as values), transform them all into an array and then pass all these elements to Sum, and Sum to sum them all. But I can't. I thought I could just push the number values into the array that I'm going to return to Sum(), but it's not working. I can access and move around the elements of the array that I use to test the function, but the number values given as parameters are just ignored, no matter where I put them in Args. My function looks something like this.
function argsPasser () {
var argz = [];
for (i = 0 ; i < arguments.length ; i++) {
if ((typeof arguments[i]) != (typeof 5)) {
for (j = 0 ; j < arguments[i][length] ; j++) {
argz.push(arguments[i][j]); }
else
argz.push(arguments[argument]; }}
return argz; }
I don't know if I'm missing something in the way the control flow, or the arguments variable behaves, but this makes perfect sense to me and I don't understand why it's not doing what I want it to do. When i (index of the argument in arguments) is 0 and j (index of values within that argument) is 0, number values should be properly added to the array, no?
More than making this particular function work, I'm very interested in learning what I can do to manipulate the arguments variable and how I can make it be flexible when it comes to making functions. So even if the problem itself has no solution, learning more about this topic would be profit for me.
Thank you in advance.

Related

Why does the code return the number of iterations that executed over the actual value?

I'm studying Javascript, I came across a typical basic for loop that was structured like this:
var myArry = [];
for (var i = 0; i < 10; i += 2){
console.log(myArry);
}
This I understand, it will return the array as a whole with the values of i specified in the counter.
However I then pasted the following code out of curiosity. To see if i'd get the same result, which was what I assumed bring. However what I got was how many iterations happened before the loop ended?
```console.log(myArry.push(i));```
I know this is trivial, but I just want to understand how the language interprets the above line as the amount of times the for loop iterated before it ends.
Is the above line of code showing how many times push is executed, or is it some other abstraction I'm missing?
Any clarification is greatly appreciated.
Thank you.
Array.push returns the number of items in the array after that push is completed. it returns the equivalent of Array.length().
See ref hre
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

Knockout observables and performances

I’m working with knockout for more than 1 year now, but there is still a problem I cannot resolve.
This is more “syntax sugar” problem, than actual problem. The code simples are in TypeScript, but it should be ok, even if you’ve never hear of it.
Let me explain.
Let’s say we we have an observable array ( MyArray) , where each element has “Value” observable. We want to create a computed observable to get a sum of all.
The evident approach is :
public SommeOne = ko.pureComputed((): number => {
var res = 0;
for (var i = 0; i < this.MyArray().length; i++) {
res += this.MyArray()[i].Value();
}
return res;
});
But in this case, the call to this.MyArray() is evaluated twice on each iteration. And “Value” once. Which is OK for small arrays (less than 1000 elements), but become a problem for bigger arrays. So, so far my solution is :
public SommeOne = ko.pureComputed((): number => {
var res = 0;
var array = this.MyArray();
for (var i = 0; i < array.length; i++) {
res += array[i].Value();
}
return res;
});
At this point we evaluate Array function only once (Still 1 evaluation for Value, but it’s ok, we need this) and it works fine.
So the final question:
How can I implement second solution without creating an intermediary “array” ?
It is fine for one array, but if you need to do subtraction between two arrays, or something more complex, this is getting out of hand fast.
You're almost certainly wasting your time worrying about these sort of optimizations. Calling this.myArray() isn't doing any significant calculation. Copying straight from the knockout source code, the logic that executes when invoking an observable or an observable array is as follows:
function observable() {
if (arguments.length > 0) {
// Write
//[Omitted since not relevant here]
}
else {
// Read
ko.dependencyDetection.registerDependency(observable);
return _latestValue;
}
}
Other than the overhead of the function invocation and the small amount of work done by the dependency detection (which is likely basically just a noop function when you aren't calling from within a computed); the observable function just returns a reference to the array or whatever object it happens to be holding at the moment, and there's very little cost for an object reference.
The length of the array simply isn't a factor. It doesn't "become a problem with bigger arrays", (at least the knockout part doesn't; the rest of the algorithm might depending on what you're doing) , and your caching of a value that knockout has already cached certainly isn't going to be a major performance gain. (It probably won't make it worse either; though I'd consider it a hit to readability since it's introducing new variables)
As with any performance question; the standard disclaimers apply: you should only be concerned with this if you've demonstrated first that this is an area of the code that needs optimization, and secondly that it's this knockout invocation that is a significant performance issue. If that's your situation, sure you can do some benchmarking to see if caching the value improves your performance any, but based on how you phrased your question it seems that there is a more basic misunderstanding here.

What are the pros and cons to assigning the end point of a for loop?

In various languages (I'm going to use JavaScript here, but I've seen it done in PHP and C++ and probably elsewhere), there seem to be a couple of ways of constructing a simple for loop. Version 1 is like:
var top = document.getElementsByTagName("p");
for (var i = 0; i < top.length; i++) {
...do something
}
Whereas elsewhere I've seen people construct the for loop like:
for (var i = 0, ii = top.length; i < ii; i++)
It seems like people do it without rhyme or reason - the same programmer will do both in the same script. Is there any reason to do one and not the other?
Cheers
In some languages, getting the length of an array or string may be an expensive operation. Since it doesn't change during the loop, doing it every time you test whether the iteration variable has reached the end is wasteful. So it's more efficient to get the length once and save it in a variable.
An example would be iterating over a string in C. In C, strlen() is an O(n) operation, because it has to search the char array looking for the terminating 0 element. If you wrote:
for (i = 0; i < strlen(string); i++)
your loop would be O(n2).
In languages like Javascript, getting the length is inexpensive, but programmers stick with their old habits. And programmers who have never even used those other languages learn idioms from the ones who did, so they use this coding style without even knowing the reason.
See this YouTube video for an explanation of how this type of thing happens in communities:
https://www.youtube.com/watch?v=b4vJ8l2NfIM

Breaking out of jQuery loop vs native JS for loop. Which is better?

First of all, apologies if the heading question doesn't exactly match with what I am going to ask.
My problem is that I want to have a loop, and the control is suppose to break out of this loop, once a condition is met.
Now, is it better to use the native JS 'for loop' and use 'return' or is it better to use the jQuery.each() and use return false, to break out of the loop?
If you can get away with using the plain old JavaScript method of looping over the collection, use it and break out normally.
Unless there is a very good reason to use jQuery.each(), I try to keep it out of my code as much as possible. It's really a very simple shortcut and by using plain old JavaScript, I can retain more control over what my code is actually doing.
I assume you mean break? Performance aside, use whatever you find clearer.
Some would argue that the terseness of for...break (or even a for with proper stopping conditions) would win over a library function that creates an anonymous function and passes control back and forth between your code and theirs and back to yours, but they both work.
If you do care about the performance aspect (and you probably shouldn't, readability is way more important for this), then for also wins -- it's not "free" to call a function for every single element and process return values for stopping conditions.
I prefer to use a plain JS loop when practical.
You have more control over the plain JS for loop because there you can return from the entire function. In a jQuery .each() loop, you can only stop the .each() iteration with a return. If you want to then return from the host function, you need to write additional code to do that. I prefer the plain JS for loop when possible.
The plain JS for loop is also a ton easier to step into, through and out of in the JS debugger. To step into the .each() loop, you have to either step through a lot of jQuery code or you have to put a breakpoint inside the .each() loop and run to that breakpoint.
For example, to return from the host function when some condition inside the loop is met, it would work like this in the two loops:
Plain JS
function findMatch(array, target) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] === target) {
return(i);
}
}
return(-1);
}
Using jQuery.each()
function findMatch(array, target) {
var found = -1;
jQuery.each(array, function (index, value) {
if (value === target) {
found = index;
return(false);
}
});
return(found);
}
Stepping through this function in the debugger to see why it is or isn't working is a ton easier in the plain JS version.
I usually prefer $.each as it looks cleaner with arrays (no i < a.length and such needed), and is closer to the foreach syntax which more comfortable languages have. Also, it has its own scope, which helps avoiding some common mistakes with closures:
for(var i = 0; i < a.length; i++) {
a[i].onclick = function() {
// this will display the index of the clicked
// element. Or maybe not?
alert(i);
}
}
Skipping levels of control (breaking multiple loops or returning from the whole function while in the middle of a loop) is not possible with $.each though, so if you need that, use for. Also, interactive debugging is more painful with function-based loops.

In a loop, do any operations in the end-condition get evaluated in every iteration?

In the following code:
for (var i = 0; i < object.length; i++){
....
}
does the operation object.length get evaluated every time in the iteration?
It would make most sense that the language will evaluate this once and save the result. However, I was reading some code where someone evaluated the operation before the loop started and stored it in a variable that was used in the end-condition.
Do different languages handle this differently? Any specific info for Javascript?
It obviously depends on the language. For JavaScript, the spec (ECMAScript §12.6.3) requires it always be evaluated each time. As an optimization, a specific JavaScript runtime could skip one or more of the length calls, if it could prove that the result would not change.
Completely depends on the language and (possibly) on what's in the loop. The compiler/interpreter may or may not be able to determine with certainty that the "length" property won't be changed by something in the loop.
In Javascript, it's a safe bet that it'll be re-evaluated. A simple property reference like that probably isn't that bad, but something like a function call could be a performance problem. edit To clarify, by "a function call" I mean code of any form that computes the loop termination condition in any way expensive enough to make you feel bad about doing it on each iteration.
Thus (pardon my jQuery),
for (var i = 0; i < $('.foo').length; ++i) { /* ... */ }
would involve a traversal of the whole DOM on each iteration.
The condition has to be re-evaluated at each iteration of the loop because in theory the value could have changed inside the loop body.
A smart compiler could automatically optimize for this case, but performing static analysis to determine that the length will not change inside the loop is extremely difficult in JavaScript. For this reason, you can say that in most cases object.length will indeed be reevaluated in each iteration.
On the other hand, it's often simpler for the programmer to reason out that the length will certainly not change, and if you're really (I mean, really) worried about performance, you could pre-compute and store the length before the loop starts.
If order doesn't matter to you, iterate backwards. You don't need the messy temporary variable holding the length in this case. The start condition of the loop is only evaluated once (obviously, it'd be pointless re-evaluating it once the loop has already started!). Using an example from an early response:
for (var i = $('.foo').length - 1; i >= 0; i--) { /* ... */ }
I know I'm answering this long after it was asked, but it's still showing high in Google search results for related queries and none of the existing answers seem to suggest this alternative approach.
In some languages this depends on the level of optimization you have configured at build-time. I believe in C++, for example, marking a field as volatile will force re-evaluation. Check out these links:
http://en.wikipedia.org/wiki/Loop_unwinding
http://msdn.microsoft.com/en-us/library/12a04hfd.aspx
In Javascript it does get evaluated every time. You can get around it by setting a "max" variable in the first part of the loop:
for (var i=0, imax=object.length; i<imax; i++) {
// statements
}
Yes it gets calculated each iteration ..
why not test it ?
var loop = 5;
for (var i = 0; i< loop; i++)
{
alert(i + ' of ' + loop);
loop--;
}
live at http://jsfiddle.net/MSAdF/

Categories

Resources