Javascript - Object Value not Updating after Moving between Arrays - javascript

I am moving one object from one holders array to another:
for (var x = 0; x < array.length; x++) {
var i = holder1.array.length - 1;
while (i >= 0) {
var object = array[holder1.array[i].index];
holder1.array[i].splice(i, 1);
object.owner = i;
object.index = x;
holder2.array.push(object);
i--;
}
}
I then change the data like so:
for (var i = 0; i < holders.length; i++) {
var holderActive = holders[i];
if (holderActive.array.length > 0) {
for (var x = 0; x < holderActive.array.length; x++) {
var object = array[holderActive.array[x].index];
console.log(object.property); << ALWAYS THE SAME!
object.property ++;
}
// ...
}
}
As you can see, I am editing the property of the object, but every time this is run, the property is logged as the same value. What is going on here?

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

Why does a tetris piece fall all at once instead of one at a time?

I am making tetris in JS. When making a block fall, it makes the block reach the bottom of the screen in one draw instead of slowly approaching the bottom. I tried creating a variable that stores the changes to be made so that it only looks at the current board, but no luck. After checking whether the output variable is == to the board, it seems like the board is changing after all, as it returns true. What's going on?
EDIT: I have successfully made a shallow copy of the array. It still falls to the bottom immediately, though. What's going on?
var data = [];
function array(x, text) {
var y = [];
for (var i = 0; i < x-1; i++) {y.push(text);}
return y;
}
for (var i=0; i<20; i++){data.push(array(10, "b"));}
function draw(){
var j;
var i;
var dataOut = [...data];
for (i = 0; i < data.length - 1; i++){
for (j = 0; j < data[i].length; j++){
if (data[i][j] == "a" && data[i + 1][j] == "b" && i < data.length - 1) {
dataOut[i][j] = "b";
dataOut[i + 1][j] = "a";
}
}
}
data = dataOut;
}
data[0][4] = 'a';
draw();
console.log(data);
In JavaScript, Arrays and Objects are passed by reference. So when you do this:
var dataOut = data;
Both of these references point to the same Array. You could clone the Array every time:
var dataOut = JSON.parse(JSON.stringify(data));
Or simply revert your loop, to go from the bottom to the top. I took the liberty of renaming the variables to make this more clear. Try it below:
var chars = {empty: '.', block: '#'},
grid = createEmptyGrid(10, 20);
function createEmptyGrid(width, height) {
var result = [], x, y;
for (y = 0; y < height; y++) {
var row = [];
for (x = 0; x < width; x++) {
row.push(chars.empty);
}
result.push(row);
}
return result;
}
function draw() {
var x, y;
for (y = grid.length - 1; y > 0; y--) {
for (x = 0; x < grid[y].length; x++) {
if (grid[y][x] === chars.empty && grid[y - 1][x] === chars.block) {
grid[y][x] = chars.block;
grid[y - 1][x] = chars.empty;
}
}
}
}
// Just for the demo
var t = 0, loop = setInterval(function () {
draw();
if (grid[0].includes(chars.block)) {
clearInterval(loop);
grid[9] = 'GAME OVER!'.split('');
}
document.body.innerHTML = '<pre style="font-size:.6em">'
+ grid.map(row => row.join(' ')).join('\n')
+ '</pre>';
if (t % 20 === 0) {
grid[0][Math.floor(Math.random() * 10)] = chars.block;
}
t++;
}, 20);

Javascript error detecting item in array

I am working on a minesweeper game in javascript. The mechanism that is causing me trouble is the for loop inside the Mine object that sets the isBomb variable to true or false.
var board = [];
var bombs = [];
var mines;
function findNeighbors(x,y) {
return 'work in progress'
}
function setup() {
// create bombs
for (var i = 0; i < 45; i++) {
var position = [floor(random(0,15)),floor(random(0,15))];
if (!bombs.includes(position)) {
bombs[i] = position;
}
}
// create board
for (var y = 0; y < 15; y++) {
board[y] = new Array();
for (var x = 0; x < 15; x++) {
board[y][x] = new Mine(y,x);
}
}
}
console.log(board);
console.log(bombs);
function Mine(x,y) {
this.x = x;
this.y = y;
this.neighbors = findNeighbors(this.x,this.y);
for (var iter = 0; iter < 45; iter++) {
if (bombs[iter] == [this.x,this.y]) {
this.isBomb = true;
}
else {
this.isBomb = false;
}
}
this.show = function() {
return 'show'
}
this.setValue = function(value) {
this.value = value;
return value;
}
}
When I type bombs[44] in the console for example, it returns something like [5,11] yet when I check if bombs[44] = [5,11] it will always return false. Is there a specific way I have to denote the [5,11] array for it to be recognized?
This is because you cannot compare two arrays in javascript. What you can do is using join() and then compare as strings in single step,
bombs[44].join(",") == [5,11].join(",")
Or you can compare the contents of the array individually
Try changing the conditional expression in your for-loop at the top for (var i = 0; i < 45; i++) to for (var i = 0; i < arr.length; i++)
this will make the loop , go over the full array length with less room for error. for loops can be , error prone and tedious.

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) { ...

finding unique values from two arrays of objects based on two keys i.e from and to in javascript

i have two arrays of objects like shown below :
var b = [{"from":2,"to":7,"id":1},{"from":3,"to":9,"id":2},{"from":2,"to":7,"id":3}]
var c = [{"from":3,"to":9,"id":2,"style":""},{"from":2,"to":7,"id":3,"style":"dash-line"},{"from":4,"to":2,"id":4,"style":"dash-line"},{"from":2,"to":4,"id":5,"style":""},{"from":4,"to":2,"id":6,"style":"dash-line"}];
what i want is an array of objects from above two , which has unique "from" ,"to" and "style" should be either ""(blank) or undefined.With unique ids.
i.e
output = [{"from":2,"to":7,"id":0},{"from":3,"to":9,"id":1},{"from":2,"to":4,"id":6,"style":""}]
am able to get it as shown in below code, but i feel code can be optimized or there can be a better way to do it. Please help....Thanks.
var b = [{"from":2,"to":7,"id":1},{"from":3,"to":9,"id":2},{"from":2,"to":7,"id":3}]
var c = [{"from":3,"to":9,"id":2,"style":""},{"from":2,"to":7,"id":3,"style":"dash-line"},{"from":4,"to":2,"id":4,"style":"dash-line"},{"from":2,"to":4,"id":5,"style":""},{"from":4,"to":2,"id":6,"style":"dash-line"}];
var a = b.concat(c);
findUniQue(a);
function findUniQue(a){
var tempArr =[];
for(var i =0;i<a.length;i++){
if(a[i].style == undefined || a[i].style != 'dash-line' ){
var count = 0;
if(tempArr.length>0){
for(var j =0;j<tempArr.length;j++){
if((a[i].from == tempArr[j].from)&&(a[i].to == tempArr[j].to)){
count--;
break;
}
else{
count++;
}
if(count == tempArr.length){
a[i].id = i;
tempArr.push(a[i]);
}
}
}
else{
a[i].id = i;
tempArr.push(a[i]);
}
}
}
console.dir(tempArr);
}
function removeduplicate(){
var array = [{id:5},{id:8},{id:9},{id:10},{id:5},{id:8}];
var size = array.length;
for (var i = 0; i < size - 1; i++) {
for (var j = i + 1; j < size; j++) {
if (array[j].id !== array[i].id)
continue;
array.splice(j,1);
j--;
size--;
} // for j
} // for i
console.log(array);
}

Categories