Array index out of bounds in Angular 2 - javascript

I want to declare an Array with 4 dimensions, then loop some stuff with for() - and then the program breaks. Here is my code:
Typescript:
MoarInfo: any = [[[[]]]];
JavaScript:
constructor(){
for(var i = 0; i < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth].length; i++){
for(var a = 0; a < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i].length; a++){
for(var b = 0; b < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a].length; b++){
this.MoarInfo[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
this.MoarInfo[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
this.MoarInfo[i][a][b][2] = 'DetailsSpan';
}
}
}
}
The Problem definitively lies at the MoarInfo[][][][] array. I tested my code without it, and it works fine. I tried the following possibilities for the Typescript array declaration as well:
Moarinfo: any[]; MoarInfo = []; MoarInfo = [[[[]]]]; MoarInfo: any[][][][] = [[[[]]]];
And in JavaScript, I tried to declare a new Array, and then push some elements on the MoarInfo array, with different functions (split, unshift, push, concat) and nothing worked.
What am I doing wrong?

Check the size of this.MoarInfo[i][a][b]. You are trying to get the value by index 0,1,2. Looks like its size is less than 2 which is causing this error.
if(this.MoarInfo[i][a][b].size > 0){
this.MoarInfo[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
}
if(this.MoarInfo[i][a][b].size > 1){
this.MoarInfo[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
}
if(this.MoarInfo[i][a][b].size > 2){
this.MoarInfo[i][a][b][2] = 'DetailsSpan';
}

Okay, I figured it out for myself. You have to set the elements of the dimensions from the array at first blank, then you can fill them with content. First I declared an Array in TypeScript like this AnArray = [];. Then I switched to JavaScript ( to the constructer() function ) and filled it with blank elements. I archieved this with this.AnArray.push();. If you want to set elements for the first dimension use push([]);, if you want an element for the 4th dimension, use push([[[]]]);. And you can set your content space like this push([[['E1',0,0,'E2']]]);. Now you can use follwing syntax:
alert( this.AnArray[0][0][0][3] ); //returns 'E2'
The complete code from my project now works fine and looks like this:
for(var i = 0; i < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth].length; i++){
this.test.push([[[]]]);
for(var a = 0; a < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i].length; a++){
this.test[i].push([[]]);
for(var b = 0; b < this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a].length; b++){
this.test[i][a].push(['',0,'']);
this.test[i][a][b][0] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][0];
this.test[i][a][b][1] = this.AllDataInfo[this.KontoAktuellYearIndex][this.KontoAktuellMonth][i][a][b][1];
this.test[i][a][b][2] = 'DetailsSpan';
}
}
}
I wonder if there is a better way than using arrays, but if you want it too, you can do it like this.
cheers

Related

Using .push stops for loop from executing

I have a for loop that suddenly stops working when I try to push to an array. The best way to describe what's going on is just to show my code and try an explain what's going on.
for (var i = 0; i < childs.length; i++) {
if (childs[i].length > 0) {
for (var j = 0; j < amountsValue[i].options.custValues.length; j++) {
var label = amountsValue[i].options.custValues[j].label;
var value = amountsValue[i].options.custValues[j].value;
for (var k = childs[i].length - 1; k >= 0; k--) {
if (childs[i][k].attributes[label] != value) {
childBackup.push(childs[i][k]);
childs[i].splice(k, 1);
}
}
}
amountsValue[i].id = childs[i][0].attributes.internalid;
childs.push(childBackup);
}
}
What's happening is I am looping through an array of items which may or may not have custom options available such as different sizes or colours. The loop will check to see if there are any then get the value and label from the array.
After this, we then loop again to try and match up the values with option values stored within a separate model. The plan is to check if the value is the same as the one stored and if not then splice it from the array. The process of elimination should eventually leave only one option left and that will be used to get the internalid.
During this a back up of the spliced objects is kept so that they can be appended to the array again so that the user can change the option they want. The problem is using childs.push(childBackup) stops the browser form reading the options on amountsValue. This works if the code is removed or it is pushed into another index so I'm really not sure why it isn't working.
Does anyone have any suggestions on how to get this working? I'm sorry if this doesn't make much sense, I've tried to explain it as best I can but let me know if anything needs to be cleared up.
EDIT: I have fixed the issue. Thank you to everyone who suggested ways to solve the problem. As others said, I was trying to manipulate the array I was looping through and changing the length on it. So that part of the code was taken outside the loop and after the initial loop another loop was set up which contained the following code:
for (var i = 0; i < childBackup.length; i++) {
childs[0].push(childBackup[i]);
}
It now works as intended. Thank you.
You are manipulating the array you are looping through.
var count = childs.length;
for (var i = 0; i < count; i++) {
if (childs[i].length > 0) {
for (var j = 0; j < amountsValue[i].options.custValues.length; j++) {
var label = amountsValue[i].options.custValues[j].label;
var value = amountsValue[i].options.custValues[j].value;
for (var k = childs[i].length - 1; k >= 0; k--) {
if (childs[i][k].attributes[label] != value) {
childBackup.push(childs[i][k]);
childs[i].splice(k, 1);
}
}
}
amountsValue[i].id = childs[i][0].attributes.internalid;
childs.push(childBackup);
}
}

for loop to print out multiple arrays with similar names

I've got multiple arrays, like so:
bugNames0 = ["wasp", "roach", "stinkbug", "mantis"];
bugNames1 = ["hornet", "beetle", "ant", "termite"];
bugNames2 = ["gnat", "fly", "grub", "chigger"];
bugNames3 = ["flea", "bed-bug","maggots", "cricket"];
Next up I have this for loop:
function bugLoop() {
for (var i=0; i < 4 ; i++){
console.log(bugNames0[i]);
}
}
That will successfully print the first array to console, or each individually if I manually update the number in the array's name.
But is there a way to do something more like this? This following code bit doesn't work, but I hope it explains what I am trying to do:
for (var i=0, j=0; i < 4; i++) {
console.log(bugNames(i)[j]);
}
}
Here i represents the bugName#, which I would like to get to update through 0 - 3 as the loop runs, printing out only the first option of each array represented by j.
Goal outcome printed to console would be:
"wasp", "hornet", "gnat", "flea"
Or something like that.
If possible I would like solutions only using vanilla JS as I'm working on a project (self assigned exercise) where I'm trying to complete it using vanilla. Kind of a force myself to get the know the language better exercise.
(Also, I've only been coding for 4 months, so sorry if this is a noob question. I couldn't find the answer online anywhere, just lots of loops on printing out arrays normally.)
If you can store your arrays within an array, that would be a better option.
For instance:
bugNames[0] = ["wasp", "roach", "stinkbug", "mantis"];
bugNames[1] = ["hornet", "beetle", "ant", "termite"];
bugNames[2] = ["gnat", "fly", "grub", "chigger"];
bugNames[3] = ["flea", "bed-bug","maggots", "cricket"];
Then you can loop through the bugNames array normally.
You could store all four arrays into one larger array (each bugNames array would simply be an element within this larger array). Let's call it bugCollection:
bugCollection = [["wasp", "roach", "stinkbug", "mantis"], ["hornet", "beetle", "ant", "termite"], ["gnat", "fly", "grub", "chigger"], ["flea", "bed-bug","maggots", "cricket"]]
Alternately, you could keep your variable storage of these arrays and say:
bugCollection = [bugNames0, bugNames1, bugNames2, bugNames3]
Then you could iterate through the larger array, logging out the index at each.
var oneFromEachArray = function(index) {
for (var i = 0; i < bugCollection.length; i++) {
console.log(bugCollection[i][index]);
}
}
oneFromEachArray(0) // Console logs 'wasp', 'hornet', 'gnat', 'flea'
You could try eval
for (var j=0; j < 4 ; j++){
for (var i=0; i < 4 ; i++){
eval("console.log(bugNames" + j + "[i]);");
}
}
You could use the function eval() like this:
for (var i=0, j=0; i < 4; i++) {
console.log(eval('bugNames' + i)[j]);
}
But did you already consider utilizing an array of arrays? Maybe that would be a cleaner way to achieve the same thing.
You can always access your variables using window object. Please use following code to access your variable dynamically.
for (var i=0, j=0; i < 4; i++) {
console.log(window["bugNames"+i][j]);
}

Name value pair list, unable to increment name width number

I'm trying to create this using a for loop.
slideArr.slide1 = 1;
slideArr.slide2 = 2;
slideArr.slide3 = 3;
So I get my total slides, loop over them like so
for ( index = 0; index < totalSlides.length; ++index )
{
slideArr.slide = index;
}
but I want the name value pair name in the case "slide" to increment as well.
for ( index = 0; index < totalSlides.length; ++index )
{
slideArr.slide1 = 1;
}
and on the second loop
for ( index = 0; index < totalSlides.length; ++index )
{
slideArr.slide2 = 2;
}
..etc..
is this possible?
I'm basically creating a name value pair list.
I would highly advise against solutions recommending slideArr["slide"+index]. This is a Code Smell and in this case it suggests you're doing something wrong. Posting your full code would help others give you better, more precise answers.
First, slideArr, to me, implies you're using an Array datatype, but you're treating it more like an Object when you call
slideArr.slide1 = 1;
If it's actually an Array, this would be pretty bad
// Don't use arrays like this !
var slideArr = [];
slideArr.slide1 = 1;
Instead, if you have an Object containing an array of slides, that might be a little better
// Use an object with an array !
var myData = {slides: []};
// Add some slides
myData.slides.push(1);
myData.slides.push(2);
myData.slides.push(3);
Now you have an array of slides within myData
console.log(myData.slides);
// => [1, 2, 3]
You can loop through that quite easily
for (var i=0; i<myData.slides.length; i++) {
console.log(myData.slides[i]);
}
Output
1
2
3
If you know the slides up front, you can define myData all in one go
var myData = {slides: [1, 2, 3]};
You can skip the .push calls above. Looping stays the same and you'll get identical output.
You can do:
slideArr["slide" + index] = index;
but I would like to add this looks weird. Are you sure this is what you want?
How about:
slideArray.slides.push(totalSlides[i]);
Try this
for ( index = 0; index < totalSlides.length; ++index )
{
slideArr["slide" + index] = index;
}

Loop through colours array with jQuery

I'm trying to give each div a different background colour. Here is my current code:
http://jsfiddle.net/Uy2FX/2/
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (i=0; i < imgColours; i++) {
$('.img').css({backgroundColor: imgColours[0]});
}
However, I'm not quite sure where this is going wrong. I understand that's probably too simple to work, but in my mind it makes sense. Could someone point me in the right direction?
There are some relevant errors in your code.
This is probably what you wanted to do:
// V1 : Basic
var imgColours = ['#FCCF94', '#C4C9E5', '#ADE3D6'];
for (var i=0; i < imgColours.length; i++) {
$('.img:eq('+i+')').css({backgroundColor: imgColours[i]});
}
But if you want to get a random color from your array, for any number of divs, and also optimise your jQuery code a bit for better performance:
// V2 : random colors
var $imgs = $('#boxes1').find('.box'),
imgsCount = $imgs.length,
coloursCount = imgColours.length;
for (var i=0; i < imgsCount; i++) {
var rnd = Math.floor(Math.random() * coloursCount),
color = imgColours[rnd];
$imgs.eq(i).css({backgroundColor: color});
}
Or, if you want to loop through the colours following the order of the array, just change the loop:
// V3 : sequential colors
// Add V2 variables here
for (var i=0; i < imgsCount; i++) {
var color = imgColours[i%coloursCount];
$imgs.eq(i).css({backgroundColor: color});
}
UPDATED FIDDLE: http://jsfiddle.net/Uy2FX/12/
For some very basic tips on jQuery selectors performance: http://www.sitepoint.com/efficient-jquery-selectors/
You are always assigning imgColours[0] to EVERY div. I think what you are looking for is imgColours[i]
You will also need to use imgColours.length to tell your loop how long the array is.
You are also grabbing all HTML elements with the class of img, so this will change all of them each time.
To grab each element separately, you can use the CSS nth-of-type selector. Basically you can just do something like
$(".img:nth-of-type(" + i + ")")
You need to use imgColours.length
The for loop has no idea how long the array is otherwise
Edit: What's the point in this for loop if you end up using imgColours[0] anyways? If you want to loop each color, use i instead of 0.
And either way, this will not achieve a different background per div.
Try selecting by className (I'm going to use vanilla.js because it's simple)
var elements = document.getElementsByClassName("img");
for (var i = 0; i<elements.length; i++) {
var color = imgColours[Math.floor(Math.random()*imgColours.length)]; //get a RANDOM color change me if needed
elements[i].style.backgroundColor = color;
}
How about this?
var ec = 0;
var i = 0;
for(ec; ec < elements.length; ec++, i++) {
elements[ec].style.backgroundColor = imgColours[i];
if(i == (imgColours.length - 1)) i = -1;
}
http://jsfiddle.net/y2dq3/

For Loop Manipulate Multidimensional Array Javascript

Okay so I have a 2D array that I am trying to alter using javascript. This is what I have so far:
for (var i = 0; i <= inputData.length; i++ {
inputData[0,0] = inputData[0,0];
inputData[i,0] = inputData[((i - 1) + 1/12), 0];
I want this to take array [i-1] value and then add 1/12 to it
for (j = 13; inputData.length; j += 13) {
delete inputData[j,0];
delete inputData[j,1];
}
Also, I want to delete the entire 2D array at every 13th increment value.
}
This is what I have so far. I am sure there are probably errors within it. Can you guys help me out here? Any help would be greatly appreciated.
Couple of things - you need to be careful when iterating over an array that you're removing from, your indexes will end up offset with respect to your data as soon as you do a delete. Secondly your syntax for deletion is off.
Normally in these situations I favour creating a new array containing the data I want to keep.
var inputData = [[1,1],[2,2],[3,3],[4,4]];
var b = [];
for (i=0; i < inputData.length; i++) {
if ((i + 1) % 13 != 0) {
var year_with_month = inputData[i][0] + i * 1/12;
var e = [year_with_month, inputData[i][1]]
b.push(e);
}
}
inputData = b;
Also, given a choice I'd use a library like underscore to make it easy to do the looping. I never manually write for loops anymore, took me a couple of attempts to get that one right :)

Categories

Resources