trouble filling bidimensional Array with objects in JavaScript - javascript

I've got this array in a "global" position (out of every function in my doc).
var arrayBidimensional;
Then, i'm trying to filling it like this:
var objetoLetra = new objectLetter("","","","","");
arrayBidimensional=new Array(tamano);
for (i=0; i <tamano; i++)
arrayBidimensional[i]=new Array(tamano);
var random = Math.floor((Math.random()*26)+0);
for (var i = tamano - 1; i >= 0; i--)
{
for (var j = tamano - 1; j >= 0; j--)
{
random = Math.floor((Math.random()*26)+0);
objetoLetra.letra = letras[random];
objetoLetra.letraposx = j;
objetoLetra.letraposy = i;
objetoLetra.formapalabra = "no";
objetoLetra.iden = j+""+i;
arrayBidimensional[i][j] = objetoLetra;
}
}
so when i tried to reach to this array in some position like array[X][X]
all i've got is the very first position. Example: if the first position (That is 0,0) is "A", then, the entire array got "A" on every single position, even if it is [(max position), (max position)].
How do i see that?, well, i'm building a Table with td-s like this:
'<td width="30">'+arrayBidimensional[i][j].letra+'</td>'
Then, the entire table is just a lot of "A" every single cell... So... What i am doing wrong?
Please and thank you!

You need to create a new objectLetter for each location in the array:
arrayBidimensional = new Array(tamano);
for (i=0; i < tamano; i++) {
arrayBidimensional[i] = new Array(tamano);
}
for (var i = tamano - 1; i >= 0; i--)
{
for (var j = tamano - 1; j >= 0; j--)
{
var objetoLetra = new objectLetter("","","","","");
var random = Math.floor((Math.random()*26)+0);
objetoLetra.letra = letras[random];
objetoLetra.letraposx = j;
objetoLetra.letraposy = i;
objetoLetra.formapalabra = "no";
objetoLetra.iden = j+""+i;
arrayBidimensional[i][j] = objetoLetra;
}
}

Here's what a Multidimensional Array should look like in JavaScript:
var multi = [['String', 0, 'something else'],['another String', 42, 'whatever']];
or
var multi = new Array(new Array('String', 0, 'something else'), new Array('another String', 42, 'whatever'));
console.log(multi[1][2]); // 'whatever'
console.log(multi[0][1]); // 0

Related

how to fill in the value in the array

i have code like this in actionscript3,
var map: Array = [
[[0,1,0],[0,1,0]],
[[0,1,0], [0,1,0]]];
var nom1: int = 0;
var nom2: int = 0;
var nom3: int = 1;
var nom4: int = 18;
stage.addEventListener (Event.ENTER_FRAME, beff);
function beff (e: Event): void
{
map[nom1][nom2][nom3] = nom4
}
stage.addEventListener (MouseEvent.CLICK, brut);
function brut(e: MouseEvent):void
{
trace (map)
}
when run, it gets an error in its output
what I want is to fill in each "1" value and not remove the "[" or "]" sign
so when var nom1, var nom2 are changed
Then the output is
[[[0,18,0],[0,18,0]],
[[0,18,0],[0,18,0]]]
please helps for those who can solve this problem
If what you want to achieve is to replace every 1 by 18 in this nested array, you could try :
for (var i = 0; i < map.length; i++) {
var secondLevel = map[i];
for (var j = 0; j < secondLevel.length; j++) {
var thirdLevel = secondLevel[j];
for (var k = 0; k < thirdLevel.length; k++) {
if (thirdLevel[k] === 1) {
thirdLevel[k] = 18;
}
}
}
}
Note that, this would only work for nested arrays with 3 levels of depth

cannot detect error. Where is the infinite loop occurring?

// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count = 0;
var array = person.split(",");
var freq = [];
var words = [];
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i = 0, j = 0;
while (array.length > 0) {
var temp = array[0];
while (j < array.length) {
if (temp == array[j]) {
count = count + 1;
array.splice(j, 1);
//console.log(array);
j = 0;
}
else {
j = j + 1;
}
}
freq[freq.length] = count;
count = 0;
words[words.length] = temp;
}
window.alert(freq + "\n" + words);
The problem is that whenever I run it an infinite loop occurs and no output is shown, I cannot find the error please help if possible. This code is for finding the frequency of the words in a input string with words separated by commas. thank u.
You just need to put var i=0,j=0; inside the while !
while(array.length>0)
{var i=0,j=0;
Working fidddle
You're resetting your loop variable j to 0 on each iteration. This condition if(temp==array[j]) never fails so j is always reset to 0, so while(j<array.length) is always true.
After coming out of the inner While loop, you need to reset j to zero. As the incremental value of j is not allowing it to go again inside the inner loop So array.length is not reducing And we are getting an infinite loop.
// JavaScript Document
var person = prompt("GIVE INPUT", "");
var count=0;
var array = person.split(",");
var freq = new Array();
var words = new Array();
//freq.fill(0);
//words.fill("");
//window.alert(freq[0]);
var i=0,j=0;
while(array.length>0)
{
var temp=array[0];
while(j<array.length)
{
if(temp==array[j])
{
count=count+1;
array.splice(j,1);
//console.log(array);
j=0;
}
else
{
j=j+1;
}
}
freq[freq.length]=count;
count=j=0;
words[words.length]=temp;
}
window.alert(freq+"\n"+words);
It's where for is more useful for consistency. You can replace inner while loop by this for loop:
for(j=a.length-1; j>=0; j--)
if(temp==a[j]) {
count=count+1;
a.splice(j,1);
}
Nevertheless, overall complexity of your counting method can be reduced with data structure like map.
Essential part of your script can be reduced to this:
var counter = new Map();
for (i in array)
counter.set(array[i], (counter.get(array[i])||0)+1);
var freq = Array.from(counter.values());
var words = Array.from(counter.keys());

Array equals itself plus number = NaN

I must be doing something stupid. The array newArea needs to add up data from all regions, i.e. be global. Regions are represented by variable p. But when I try to get newArea array to add to itself, e.g. newArea[p] += otherArray, it outputs NaNs. Even newArea[p] += 1 outputs NaNs.
Can anyone spot what I'm doing wrong? It's driving me mad and I'm working to a deadline.
mm=0
var maxVolume = 0;
var tempCAGR = 0;
var maxCAGR = 0;
var newArray = [];
var newRegions = [];
var newConsValues = [];
var newArea = [];
for (var p=0; p<arrayRef[mm].length; p++) {//9 regions
newArray[p] = [];
for (var q=0; q<arrayRef[mm][p].length; q++) {//4 scenarios
newArea[q] = [];
if (q==0) {
newRegions.push(arrayRef[mm][p][q][0]);
newConsValues.push(arrayRef[mm][p][q][1]);
}
for (var r=0; r<dates.length; r++) {//time
//console.log('p: '+p+', q: '+q+', r: '+r);
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
}
arrayRef[mm][p][q].shift();
tempCAGR = Math.pow(( arrayRef[mm][p][q][len] / arrayRef[mm][p][q][1] ),(1/len))-1;
//console.log(newRegions[p]+', num: '+arrayRef[mm][p][q][len-1]+', denom: '+arrayRef[mm][p][q][0]+', len: '+len+', cagr: '+tempCAGR);
newArray[p][q] = tempCAGR;
maxCAGR = Math.max(maxCAGR,tempCAGR);
}
}
console.log(newArea);
You are cleaning the array in newArea everytime you loop through it:
...loop q ...
newArea[q] = []; // <-- resets the array at q pos
... loop r ...
if (p==0) {
newArea[q][r] = 1;
} else {
newArea[q][r] += 1;
}
So when p === 0 it will fill an array at q pos of your newArea array. However, next iteration of p will clear them out, so there's nothing there to sum.
You probably want to keep the old array or create a new one if there isn't one.
newArea[q] = newArea[q] || [];
It looks like you do not have the variable initialised. With adding something to undefined, you get NaN.
You can change the art of incrementing with a default value:
if (p == 0) {
newArea[q][r] = 1;
} else {
newArea[q][r] = (newArea[q][r] || 0) + 1;
}

Speeding up simple math operations on numeric 2D array (matrix) in JavaScript

I have a numeric 2D array (an array of arrays, or a matrix) and I need to do simple matrix operations like adding a value to each row, or multiplying every value by a single number. I have little experience with math operations in JavaScript, so this may be a bone-headed code snippet. It is also very slow, and I need to use it when the number of columns is 10,000 - 30,000. By very slow I mean roughly 500 ms to process a row of 2,000 values. Bummer.
var ran2Darray = function(row, col){
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var myArray = ran2Darray(5, 100);
var offset = 2;
for (i = 0; i < myArray.length; i++) {
aRow = myArray[i];
st = Date.now();
aRow.map(function addNumber(offset) {myArray[i] + offset*i; })
end = Date.now();
document.write(end - st);
document.write("</br>");
myArray[i] = aRow;
}
I want to avoid any added libraries or frameworks, unless of course, that is my only option. Can this code be made faster, or is there another direction I can go, like passing the calculation to another language? I'm just not familiar with how people deal with this sort of problem. forEach performs roughly the same, by the way.
You don't have to rewrite array items several times. .map() returns a new array, so just assign it to the current index:
var myArray = ran2Darray(5, 100000);
var offset = 2;
var performOperation = function(value, idx) {
return value += offset * idx;
}
for (i = 0; i < myArray.length; i++) {
console.time(i);
myArray[i] = myArray[i].map(performOperation)
console.timeEnd(i);
}
It takes like ~20ms to process.
Fiddle demo (open console)
Ok, Just a little modification and a bug fix in what you have presented here.
function addNumber(offset) {myArray[i] + offset*i; }) is not good.
myArray[i] is the first dimention of a 2D array why to add something to it?
function ran2Darray (row, col) {
var res = [];
for (var i = 0 ; i < row; i++) {
res[i] = [];
for (var j = 0; j < col; j++) {
res[i][j] = Math.random();
}
}
return res;
}
var oneMillion = 1000000;
var myArray = ran2Darray(10, oneMillion);
var offset = 2;
var startTime, endTime;
for (i = 0; i < myArray.length; i++) {
startTime = Date.now();
myArray[i] = myArray[i].map(function (offset) {
return (offset + i) * offset;
});
endTime = Date.now();
document.write(endTime - startTime);
document.write("</br>");
}
try it. It's really fast
https://jsfiddle.net/itaymer/8ttvzyx7/

detecting range overlaps in Google Calendar-Style event list

I need help fixing my existing code to accomplish what I am trying to do.
with the following sample data:
var SAMPLE_DATA = [{start: 30, end: 150}, {start: 540, end: 600}, {start: 560, end: 620}, {start: 610, end: 670}];
I need to do the following:
iterate through each sample object
determine if the current objects range (obj.start:obj.end) overlaps with any other object ranges.
record the total number of overlaps for that object into totalSlots property
determine the "index" of the object (used for it's left-to-right positioning)
mockup of what I am trying to accomplish:
As you can see in the mockup, slotIndex is used to determine the left-to-right ordering of the display. totalSlots is how many objects it shares space with (1 meaning it is the only object). 100 / totalSlots tells me how wide the square can be (i.e. totalSlots=2, means it is 100 / 2, or 50% container width).
Current Output from my code
Obj[0] slotIndex=0, totalSlots=0
Obj[1] slotIndex=1, totalSlots=1
Obj[2] slotIndex=1, totalSlots=2
Obj[3] slotIndex=0, totalSlots=1
expected/desired output from my code:
Obj[0] slotIndex=0, totalSlots=0
Obj[1] slotIndex=0, totalSlots=1
Obj[2] slotIndex=1, totalSlots=2
Obj[3] slotIndex=0, totalSlots=1
the code:
detectSlots: function(oldEventArr) {
oldEventArr.sort(this.eventSorter);
var newEventArr = [],
n = oldEventArr.length;
for (var i = 0; i < n; i++) {
var currObj = oldEventArr[i];
if ('undefined' == typeof currObj.totalSlots) {
currObj.slotIndex = 0;
currObj.totalSlots = 0;
}
for (var x = 0; x < n; x++) {
if (i == x) {
continue;
}
var nextObj = oldEventArr[x];
if (currObj.start <= nextObj.end && nextObj.start <= currObj.end) {
currObj.totalSlots++;
nextObj.slotIndex++;
}
}
newEventArr.push(currObj);
}
return newEventArr;
}
Please help me figure out what is going wrong in my code. I'm about 90% sure the problem lies in the if(currObj.start <= nextObj.end && nextObj.start <= currObj.end) statement where I am assigning/incrementing the values but I could use an extra set of eyes on this.
The slotIndex value can be calculated by using graph colouring algorithm. Note that brute force algorithm is exponential in time and will only be a viable solution for a small set of overlapping slots. Other algorithms are heuristics and you won't be guaranteed the least slot possible.
Here is an example of heuristic for your problem:
...
// init
var newEventArr = [], n = oldEventArr.length;
for (var i = 0; i < n; i+=1) {
var currObj = oldEventArr[i];
newEventArr.push({"start":currObj.start,"end":currObj.end,"slotIndex":undefined,"totalSlots":0});
}
var link = {};
// create link lists and totals
for (var i = 0; i < n; i+=1) {
var currObj = newEventArr[i];
if (!link.hasOwnProperty(""+i))
link[""+i] = {};
for (var j = i+1; j < n; j+=1) {
var nextObj = newEventArr[j];
var not_overlap = (currObj.end <= nextObj.start || nextObj.end <= currObj.start);
if (!not_overlap) {
currObj.totalSlots+=1;
nextObj.totalSlots+=1;
link[""+i][""+j] = 1;
if (!link.hasOwnProperty(""+j))
link[""+j] = {};
link[""+j][""+i] = 1;
}
}
}
var arrities = [];
for (var i = 0; i < n; i+=1) {
arrities.push( {"arrity":newEventArr[i].totalSlots, "indx":i} );
}
// sort by arrities [a better solution is using a priority queue]
for (var i = 0; i < n-1; i+=1) {
var current_arrity = -1, indx = -1;
for (var j = i; j < n; j+=1) {
if (arrities[j].arrity > current_arrity) {
indx = j;
current_arrity = arrities[j].arrity;
}
}
var temp = arrities[i];
arrities[i] = arrities[indx];
arrities[indx] = temp;
}
for (var i = 0; i < n; i+=1) {
var nodeIndex = arrities[i].indx;
// init used colors
var colors = [];
for (var j = 0; j < n; j+=1) {
colors.push(0);
}
//find used colors on links
for (var k in link[""+nodeIndex]) {
var color = newEventArr[k].slotIndex;
if (color || color === 0)
colors[color] += 1;
}
//find the first unused color
for (var j = 0; j < n; j+=1) {
if (colors[j] <= 0) {
// color the node
newEventArr[nodeIndex].slotIndex = j;
break;
}
}
}
return newEventArr;
...
like this
var not_overlap = (currObj.end <= nextObj.start || nextObj.end <= currObj.start);
if (!not_overlap) { ...
or
var overlap = (currObj.end > nextObj.start && nextObj.end < currObj.start);
if (overlap) { ...

Categories