Looping over undefined array keys - javascript

Problem:
I have a DB containing math exercises, split by difficulty levels and date taken.
i want to generate a diagram of the performance over time.
to achieve this, i loop through the query results, and ++ a counter for the level and day the exercise was taken.
example: level 2 exercise was taken at 01.11.2015.
this.levels[2].daysAgo[1].amountTaken++;
with this, i can build a diagram, where day 0 is always today, and the performance over days is shown.
now levels[] has a predefined amount of levels, so there is no problem with that.
but daysAgo[] is very dynamic (it even changes daily with the same data), so if there was only one exercise taken, it would wander on a daily basis (from daysAgo[0] to daysAgo[1] and so on).
the daysAgo[] between that would be empty (because there are no entries).
but for evaluating the diagram, i need them to have an initialized state with amountTaken: 0, and so on.
problem being: i can't know when the oldest exercise was.
Idea 1:
First gather all entries in a kind of proxy object, where i have a var maxDaysAgo that holds the value for the oldest exercise, then initialize an array daysAgo[maxDaysAgo] that gets filled with 0-entries, before inserting the actual entries.
that seems very clumsy and overly complicated
Idea 2:
Just add the entries this.level[level].daysAgo[daysAgo].amountTaken++;, possibly leaving the daysAgo array with a lot of undefined keys.
Then, after all entries are added, i would loop over the daysAgokeys with
for (var i = 1; i < this.maxLevel; i++) { // for every level
for (var j = 0; j < this.levels[i].daysAgo.length; j++) {
but daysAgo.lengthwill not count undefined fields, will it?
So if i have one single entry at [24], length will still be 1 :/
Question:
How can I find out the highest key in an array and loop until there, when there are undefined keys between?
How can i adress all undefined keys up until the highest (and not any more)?
Or: what would be a different, more elegant way to solve this whole problem altogether?
Thanks :)

array.length returns one higher than the highest numerical index, so can be used to loop though even undefined values
as a test:
var a=[]
a[24]=1
console.log(a.length)
outputs 25 for me (in chrome and firefox).

Related

Why do the following two pieces of code run so differently?

Look at these two pieces of code, the second only add the third line. But time is 84 times. Anybody can explain why?
let LIMIT = 9999999;
let arr = new Array(LIMIT);
// arr.push(1);
console.time('Array insertion time');
for (let i = 1; i < LIMIT; i++) {
arr[i] = i;
}
console.timeEnd('Array insertion time');
let LIMIT = 9999999;
let arr = new Array(LIMIT);
arr.push(1);
console.time('Array insertion time');
for (let i = 1; i < LIMIT; i++) {
arr[i] = i;
}
console.timeEnd('Array insertion time');
The arr.push(1) operation creates a "sparse" array: it has a single element present at index 9999999. V8 switches the internal representation of such a sparse array to "dictionary mode", i.e. the array's backing store is an index→element dictionary, because that's significantly more memory efficient than allocating space for 10 million elements when only one of them is used.
The flip side is that accessing (reading or writing) elements of a dictionary-mode array is slower than for arrays in "fast/dense mode": every access has to compute the right dictionary index, and (in the scenario at hand) the dictionary has to be grown several times, which means copying all existing elements to a new backing store.
As the array is filled up, V8 notices that it's getting denser, and at some point transitions it back to "fast/dense mode". By then, most of the slowdown has already been observed. The remainder of the loop has some increased cost as well though, because by this time, the arr[i] = i; store has seen two types of arrays (dictionary mode and dense mode), so on every iteration it must detect which state the array is in now and handle it accordingly, which (unsurprisingly) costs more time than not having to make that decision.
Generalized conclusion: with JavaScript being as dynamic and flexible as it is, engines can behave quite differently for very similar-looking pieces of code; for example because the engine optimizes one case for memory consumption and the other for execution speed, or because one of the cases lets it use some shortcut that's not applicable for the other (for whatever reason). The good news is that in many cases, correct and understandable/intuitive/simple code also tends to run quite well (in this example, the stray arr.push looks a lot like a bug).

How to manage time complexity while working with array comparision using javascript

I need some help. here I am comparing the array's one value with next value using for loop in JavaScript but for long array its taking too much time. I am explaining my code below.
const data = [1,2,3,4,5....1000]
let compareArr = [];
for (let i=0;i<data.length;i++) {
for(let j=i+1;j<data.length;j++) {
compareArr.push(data[i] & data[j]);
}
}
console.log(compareArr)
Here I am using the bitwise AND operator to compare within values one one array but for small length array its ok but if the array length is more than 100 it its taking too much time so here my concern is in which way I can reduce the time complexity of the execution.

Find k number of array elements having the minimum difference amongst themselves

So basically I have an array of n integers (positive only). I want to have k number of integers from this array into a separate array (k<n) such that the difference between these k numbers is the minimum amongst every other k pairs of integers in an array.
If k is 1, I just need to return the max integer of the array.
I want to implement this in JavaScript. I understand how to run this problem for the values k=1 and k=2. But I don't grasp the general concept of this problem.
For eg:
Array = [6,22,21,63,99,77]
I sorted this array in ascending order. After this I don't understand how to proceed further.
After sorting the array it becomes similar to a sliding window problem.
Run a loop from i=0 to n-k and check the following.
Find the minimum difference between arr[i+k] and arr[i]. The index at which this occurs is your subset of k integers you want.
You can check this link for more details and coding help.

Array.length longer than array

I am getting some strange behaviour out of JavaScript array.length. In particular, I have an array that returns length as 3, when there is only one element in the array, at index 0. I've read this question/answer dealing with incorrect values returned by array.length, but it doesn't answer my question because my array doesn't seem to be associative.
Here's a screenshot of my console, demonstrating the odd behaviour.
The code is throwing an error because I'm looping over the first array using array.length and the code is trying to acccess the second and third elements it thinks should be in the array, and not finding them. Other entries in the database seem to not have this problem (see the second array in the screenshot).
So here's the question: Why is array.length in the first array 3 instead of 1?
The length Array property in javascript is writable from anyone and is not a reliable source to find the number of elements in the array.
Usually, it is safe to assume that the array has length elements in it, but sometime you can have different behaviours. This one is one of them.
var x = [1,2,3];
x.length = 5;
using a for construct will lead to some undefined values
for (var i = 0; i < x.length; i++) {
alert(x[i]);
}
using the forEach Array method would result (on Firefox at least) in the desired behaviour.
x.forEach(function(item) {
alert(item);
});
Note that, if you change the array length to a lesser value than the real value, the array would lose the extra elements and if you restore the original value the extra elements will be lost forever.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length

Javascript array splice causing out of memory exception?

I am basically trying to sort an input of numbers on the fly by inserting the numbers to the correct position (not 100% sure but this should be insertion sort). My understanding is that to insert into an array in javascript you need to use the array splice method http://www.w3schools.com/jsref/jsref_splice.asp .
My code in attempt of achieving my goal is as below:
var N = parseInt(readline());
var powers = [0];
for (var i = 0; i < N; i++) {
var pi = parseInt(readline());
for(var j=i;j<powers.length; j++ ){
if(powers[j]>pi){
powers.splice(j,0,pi);
}
else if(j+1==powers.length){
powers[j+1]=pi;
}
}
}
When I run this code I get an out of memory exception. I just want to understand is what I am doing wrong in the code above. If I am using the splice method wrong and it is the cause of the memory leak, what is actually happening under the hood?
I know there are other ways I could do this sorting but I am particularly interested in doing an insertion sort with javascript arrays.
In your else condition, you're adding to the array, making it one longer. That means when the loop next checks powers.length, it will be a higher number, which means you'll go into the loop body again, which means you'll add to the array again, which means you'll go back into the loop body again, which means...you see where this is going. :-)
Once you've added the number to the array (regardless of which branch), exit the loop (for instance, with break).
Side note: You won't be doing a proper insertion sort if you start j at i as you are currently. i is just counting how many entries the user said they were going to enter, it's not part of the sort. Consider: What if I enter 8 and then 4? If you start j at i, you'll skip over 8 and put 4 in the wrong place. j needs to start at 0.

Categories

Resources