Rotating a rectangular array in JavaScript - javascript

I am trying to make a Tetris game. I am trying to work on a function that rotates a 2D variable array 90 degrees (or -90).
For example, given an array like:
"-T-",
"TTT"
It would output:
"T-",
"TT",
"T-"
I have tried this function:
function rotateN90(a){
var temp = [];
for(var x = 0; x<a[0].length; x++){
temp.push("");
for(var y = 0; y<a.length; y++){
temp[x] += a[y][x];
}
}
return temp;
}
But it does not give the desired result. While it does rotate the first T-Block example given -90 degrees once, afterwards it reverts to it's original state.
Please help!
(PS: I am using KA's processing environment, so I can't use libraries or ES6)

The following code is to rotate a mxn size array to -90 degree.
function rotateN90(a){
var temp = new Array(a[0].length); // number of columns
var i=0;
for (i = 0; i < temp.length; i++) {
temp[i] = [];
}
for(i=0;i<a.length;i++){
for(let j = 0; j<a[0].length;j++){
temp[j][i]= a[i][a[i].length-1-j];
}
}
return temp;
}
If your array is :
[[1, 2,3],[4, 5, 6]]
It will rotate -90 degree and returned array will be
[[3, 6],[2, 5],[1, 4]]

class Array2D extends Array {
constructor(width, height, array) {
super();
this.width = width;
this.height = height;
for(let i = 0; i < width*height; i++) {
this[i] = array ? array[i]:0;
}
}
set(x, y, value) {
this[x+y*this.width] = value;
}
get(x, y) {
return this[x+y*this.width];
}
static swap(array2d) {
const result = new Array2D(array2d.height, array2d.width);
for(let x = 0; x < array2d.width; x++) {
for(let y = 0; y < array2d.height; y++) {
result.set(y, x, array2d.get(x, y));
}
}
return result;
}
static flip(array2d) {
const result = new Array2D(array2d.width, array2d.height);
for(let x = 0; x < array2d.width; x++) {
for(let y = 0; y < array2d.height; y++) {
result.set(x, array2d.height-1-y, array2d.get(x, y));
}
}
return result;
}
static spin(array2d) {
const swapped = Array2D.swap(array2d);
return Array2D.flip(swapped);
}
}
const a2d = new Array2D(2, 2, [1, 1, 1, 0]);
console.log(Array2D.spin(Array2D.spin(a2d)));
This should do the job, changed format though a little.
Because class notation isn't allowed in khan academy here is a modified solution
//technically this one is a little unnessecary, but I like the organization
function create2D(width, height, array) {
var arr = [];
arr.width = width;
arr.height = height;
for(var i = 0; i < width*height; i++) {
arr[i] = array ? array[i]:0;
}
return arr;
}
function set(array, x, y, value) {
array[x+y*array.width] = value;
}
function get(array, x, y) {
return array[x+y*array.width];
}
function swap(array2d) {
var result = create2D(array2d.height, array2d.width);
for(var x = 0; x < array2d.width; x++) {
for(var y = 0; y < array2d.height; y++) {
set(result, y, x, get(array2d, x, y));
}
}
return result;
}
function flip(array2d) {
var result = create2D(array2d.width, array2d.height);
for(var x = 0; x < array2d.width; x++) {
for(var y = 0; y < array2d.height; y++) {
set(result, x, array2d.height-1-y, get(array2d, x, y));
}
}
return result;
}
function spin(array2d) {
return flip(swap(array2d));
}
var a1 = create2D(2, 2, [1, 1, 1, 0]);
var a2 = spin(spin(a1));
console.log(a2);

This answer would work for flipping 90 AND flipping -90
a truthy value in the left parameter would flip it -90
a falsey value in the left parameter would flip it +90
//1 to rotate left, 0 to rotate right
function rotate(arr,left){
var newArr=[]
arr.forEach(function(a){newArr.push(a.toString())})
arr=newArr //we gonna do some wild stuff so this is to not mess with the original array given to function
arr=arr.map(function(a){return a.split``})
var newArr=new Array(arr[0].length)
for(var i=0;i<newArr.length;i++){newArr[i]=[]}
arr.forEach(function(a,i){
a.forEach(function(b,j){
newArr[j][i]=b
})
})
if(left){
newArr=newArr.map(function(a){return a.join``})
return(newArr)
}
//else(right)
newArr.map(function(a){a.reverse()})
newArr=newArr.map(function(a){a.join``})
return(newArr)
}
//example 1 (-90 degrees)
console.log("example 1(-90 degrees)",rotate(["-T-","TTT"],1))
//same example but you can use truthy or falsy values not JUST 1 or 0
console.log("example 1(-90 degrees) with another truthy value",rotate(["-T-","TTT"],{a:true}))
//example 2(+90 degrees)
console.log("example 2(+90 degrees)",rotate(["-T-","TTT"],0))

Related

null == 0 returning true in function

I have the following function that makes absolutely no sense why it fails:
function GetPlayersMap ( map, id ){
let compressedMap = [];
for(let x = 0; x < map.length; x++){
for(let y = 0; y < map[x].length; y++){
if(map[x][y].claimant_id != null) {console.log(map[x][y].claimant_id); console.log(id)}
if(id == null || map[x][y].claimant_id != id){
map[x][y].count = null;
}
if(map[x][y].claimant_id != null){
console.log(map[x][y]);
compressedMap.push(map[x][y]);
}
}
}
return compressedMap;
}
map is a 2d array of objects, map.count is an int that is never null when entering the function. id is an int that can be null. The expected result is that on an id input of 0 it return a compressedMap with one object that matched that. The function is called twice, with the same map and an id of 0 then null. What is printed in console is
0
0
Tile { x: 0, y: 0, claimant_id: 0, count: null, fake_claimed: false }
0
null
Tile { x: 0, y: 0, claimant_id: 0, count: null, fake_claimed: false }
This is printed regardless of if I change the 5th line to
if(id == null){
(which makes no sense, this means it is matching 0 to null)or
if(map[x][y].claimant_id != id){
Only when I change it to
if(false){
do I get the expected output of
0
0
Tile { x: 0, y: 0, claimant_id: 0, count: 1, fake_claimed: false }
0
null
Tile { x: 0, y: 0, claimant_id: 0, count: 1, fake_claimed: false }
I added a simplified example of the code
class Tile {
constructor(x, y) {
this.x = x;
this.y = y;
this.claimant_id = null;
this.count = 1;
this.fake_claimed = false;
}
}
var map = []
for (let x = 0; x < 1000; x++) {
map.push([]);
for (let y = 0; y < 1000; y++) {
map[x].push(new Tile(x, y));
}
}
map[0][0].claimant_id = 0;
function GetPlayersMap(map, id) {
let compressedMap = [];
for (let x = 0; x < map.length; x++) {
for (let y = 0; y < map[x].length; y++) {
if (map[x][y].claimant_id != null) {
console.log(map[x][y].claimant_id);
console.log(id)
}
if (id == null || map[x][y].claimant_id != id) {
map[x][y].count = null;
}
if (map[x][y].claimant_id != null) {
console.log(map[x][y]);
compressedMap.push(map[x][y]);
}
}
}
return compressedMap;
}
GetPlayersMap(map, 0);
GetPlayersMap(map, null);
GetPlayersMap(map, 0);
map.count is an int that is never null when entering the function.
I kindly disagree with that statement since because you don't copy the array or the objects nested inside so that map[x][y].count = null; will edit the array/object permanent. This might lead to the impresiion that null==0 though the code was never executed in that call.
Below the code with a deep-copy. Does this answer your question?
Since you have allot of data, I assume give the post about deep-copy a read.
class Tile {
constructor(x, y) {
this.x = x;
this.y = y;
this.claimant_id = null;
this.count = 1;
this.fake_claimed = false;
}
}
var map = []
for (let x = 0; x < 10; x++) {
map.push([]);
for (let y = 0; y < 10; y++) {
map[x].push(new Tile(x, y));
}
}
map[0][0].claimant_id = 0;
function GetPlayersMap(map, id) {
// added copy of array
const copy = JSON.parse(JSON.stringify(map));
let compressedMap = [];
for (let x = 0; x < copy.length; x++) {
for (let y = 0; y < copy[x].length; y++) {
if (id == null || copy[x][y].claimant_id != id) {
copy[x][y].count = null;
}
if (copy[x][y].claimant_id != null) {
console.log(copy[x][y]);
compressedMap.push(copy[x][y]);
}
}
}
return compressedMap;
}
GetPlayersMap(map, 0);
GetPlayersMap(map, null);
GetPlayersMap(map, 0);

create a grid array in JavaScript

I want to setup a grid containing m * n objects. This grid got a width of m rows and n columns.
I tried this code first
let map = [][]; // Create an array that takes a x and y index
function createMap() {
for (let x = 0; x < columnCount; x++) {
for (let y = 0; y < rowCount; y++) {
addCell(x, y);
}
}
}
function addCell(x, y) {
map[x][y] = cell(); // create a new object on x and y
}
Obviously this is a wrong syntax. The initialization of map is wrong. How can I create the array that I can access a object by passing in the x and y coordinate to the array?
Let's say I want to access the object on (3|7) I want to go for map[3][7].
Is that possible?
You cant initialize a 2d array, as there are no real 2d arrays in js. However you could setup a regular array, and add arrays to it:
function createMap(columnCount, rowCount) {
const map = [];
for (let x = 0; x < columnCount; x++) {
map[x] = []; // set up inner array
for (let y = 0; y < rowCount; y++) {
addCell(map, x, y);
}
}
return map;
}
function addCell(map, x, y) {
map[x][y] = cell(); // create a new object on x and y
}
const map = createMap(10, 10);
You aren't actually that far off with your solution. You're right, though, you cannot initialize a two-dimensional array like let a = [][]. If you add just one line to your for-loops, your solution also produces a map-like structure:
In your createMap() function, you just need to initialize every field of the the array with an array, after that you can fill the fields of this array:
function createMap() {
for (let x = 0; x < 10; x++) {
map[x] = []; // initialize map[x] as an array
for (let y = 0; y < 10; y++) {
addCell(x, y);
}
}
}
And initialize map as a simple array.
Here is a working example:
let map = [];
createMap();
console.log(map);
function createMap() {
for (let x = 0; x < 5; x++) {
map[x] = [];
for (let y = 0; y < 5; y++) {
addCell(x, y);
}
}
}
function addCell(x, y) {
map[x][y] = cell(x,y); // create a new object on x and y
}
function cell(x,y) {
return (x+1)+":"+(y+1);
}
You need a single array as value and a check if one row does not exist.
function createMap(rowCount, columnCount) {
for (let x = 0; x < rowCount; x++) {
for (let y = 0; y < columnCount; y++) {
addCell(x, y);
}
}
}
function addCell(x, y) {
map[x] = map[x] || [];
map[x][y] = x + '|' + y;
}
var map = [];
createMap(4, 8);
console.log(map[3][7]);
console.log(map);
An approach by using Array.from.
function createMap(rowCount, columnCount) {
map = Array.from(
{ length: rowCount }, // take rowCount as length
(_, i) => Array.from( // fill with new array
{ length: columnCount }, // take columnCount for every row
(_, j) => [i, j].join('|') // initialize cell with some value
)
);
}
var map;
createMap(4, 8);
console.log(map[3][7]);
console.log(map);
Not sure if you are having trouble creating the grid or displaying it.
Here is yet another way to create it:
const grid = Array.from(new Array(5),(_,x)=>Array.from(new Array(5),(_,y)=>addCell(x,y)));
Here are 2 ways to show the grid:
const grid = Array.from(new Array(5),()=>Array.from(new Array(5),()=>"-"));
const rotate = grid =>
grid[0].map(
(_,y)=>grid.map(
(_,x)=>[y,x]
)
).map(
row=>row.map(([x,y])=>grid[y][x])
);
const format = grid => grid.map(x=>x.join(" ")).join("\n");
//set some values of grid
[[0,2],[1,2],[2,2],[3,2],[4,2]].forEach(
([x,y])=>grid[x][y]="X"
);
//you can map the grid to columns first, it'll look like it's rotated
// unless you generate the columns in div float lefts
console.log("map grid columns first:")
console.log(format(grid));
//you can rotate the grid to build each row and then each column like html table
console.log("map grid rows first:")
console.log(format(rotate(grid)));
var grid=[];
var grid_length=10; //mathematical length
var grid_width=10; //mathematical width
function pos(x,y){
return (y*grid_length)-grid_length-1+x-2;
}
function replaceItem(x,y,item){
grid[pos(x,y)]=item;
}
var itemsRequested=[];
function iRequest(x,y){ // get Item on grid.
itemsRequested.push(grid[pos(x,y)]); // this both adds the Object to a list and returns it
return grid[pos(x,y)];
}
This method only makes a mathematical grid, with which you can reference with the pos() function.
Then to answer your question to get the object on 3,7 you would simply say
var a=iRequest(3,7);
//currently would return undefined because there are no objects in the array.
When using this method, 1,1 is the top left corner, and pos(1,1) would return 0.
Here's a functional method that doesn't rely on any reassignment or mutation:
const lengthX = 5;
const lengthY = 2;
const map = Array.from({ length: lengthX }, (_, colIndex) => (
Array.from({ length: lengthY }, (_, rowIndex) => (
// some element to put in each, for example
{ foo: 'bar'}
))
));
console.log(map);
The colIndex and rowIndex are optional, they're not used in this snippet, but if you need to create elements based on their location in the grid, they're the variables to use.
try this:
var x = new Array(10);
for (var i = 0; i < 10; i++) {
x[i] = new Array(20);
}
x[5][12] = 3.0;

Function to multiply a number (x) by a given number (y) a certain number of times (n)

I'm trying to write a function that will multiply a number (x) by a given number (y) a certain number of times (n). The results are to be returned in an array.
function multiplyBy(x, y, n) {
var arr = [],
z = x * y,
sum = 0;
for (var i = 0; i < n; i++) {
sum += z;
arr.push(sum);
}
return arr;
};
http://jsfiddle.net/marcusdei/s91pm82b/4/
This should work.
function multiplyBy(x, y, n) {
var arr = [];
var tot = x*y;
for (var i=0; i<n; i++){
arr.push(tot);
tot *= y;
}
return arr;
};
alert(multiplyBy(2,4,6))
As you mentioned multiplyBy(2, 4, 6); and desired out put is 8,32,128,512,2048,8192
function multiplyBy(x, y, n) {
var arr = [],
var z = x * y;
for (var i = 0; i < n; i++) {
arr.push(z);
z *= y;
}
return arr;
};
document.getElementById('choice').innerHTML = multiplyBy(2, 4, 6);
#hidden {
display:none
}
<div id="choice"></div>
<div id="hidden"></div>
Do you need something like this updated fiddle?
UPDATE 2:
function multiplyBy(x, y, n) {
var arr = [],
z = x * y,
sum = 0;
arr[0] = x * y;
for (var i = 1; i < n; i++) {
sum = arr[i - 1] * y;
arr.push(sum);
}
return arr;
};
Here's a more parsimonious function.
JS:
function multiply(op1, op2, n) {
for(var results = []; n > 0; results.push(op1 *= op2), n--);
return results;
}
console.log(multiply(2, 4, 6));

Is it possible to define and initialize multidimensional arrays in JavaScript in one line of code?

Sorry if this is too basic, but I am struggling at defining 4-dimensional array (of size 6x6x6x6) in JavaScript and initializing it to all 1's. What's the easiest way to do this?
Thanks!
You can use the literal syntax, but it would be very big and cumbersome. You may want to try something like this:
var x = [1, 1, 1, 1, 1, 1];
for (var i = 1; i < 4; i++) {
x = [x, x, x, x, x, x];
}
I found a slightly simpler solution:
var x = 1;
for (var i = 0; i < 4; i++) {
x = [x, x, x, x, x, x];
}
Seems like there should be easier way, but this will do it.
var array = [];
for(var i=0; i<6; i++) {
for(var j=0; j<6; j++) {
for(var k=0; k<6; k++) {
for(var l=0; l<6; l++) {
array[i][j][k][l]=1;
}
}
}
}
Edit
To generate an n-dimensional AxBxCxDx... array (untested):
Array.prototype.fill = function(elem, n) {
for(var i=0; i<n; i++, this.push(elem));
}
function generateArray() {
var dimensions = Array.prototype.slice.call(arguments);
var x = 1;
for (var i = dimensions.length-1; i >= 0; i--) {
x = [].fill(x, dimensions[i]);
}
return x;
}
to generate a 2x3x4x5 matrix:
generateArray(2,3,4,5);
I implemented ddlshack's generalized method, but ran into an issue due to the fact that arrays are "pass by reference" in JavaScript. This resulted in each dimension of the array holding multiple references to the same array rather than copies of it. To correct the issue, I implemented the solution as follows (the only other difference being that I used a second function rather than modify Array's prototype).
var fillArray = function(val, dim) {
var a = [];
for (var i = 0; i < dim; i++) {
if (Object.prototype.toString.call(val) === "[object Array]") {
val = val.slice(0);
}
a.push(val);
}
return a;
};
var generateArray = function() {
var dimensions = Array.prototype.slice.call(arguments),
val = 0;
for (var i = (dimensions.length - 1); i >= 0; i--) {
val = fillArray(val, dimensions[i]);
}
return val;
};

Creating a 2d array of objects in javascript

I have a javascript object -
cell{xPos, yPos};
I would like to create a 2d array of this object.
cellPrototype = function(x, y) {
this.xPos = x;
this.yPos = y;
}
var cell = new Array();
for(var i=0;i<10;i++)
{
cell[i] = new Array();
for(var j=0;j<10;j++)
{
cell[i][j] = new cellPrototype(i,j);
}
}
This code doesn't work.
Neither does -
var cellPrototype = function(x, y) {
return {
xPos : x;
yPos : y;
}
var cell = new Array();
for(var i=0;i<10;i++)
{
cell[i] = new Array();
for(var j=0;j<10;j++)
{
cell[i][j] = new cellPrototype(i,j);
}
}
So how do I create a 2d array of an object in javascript?
This works fine for me, I'm not sure if that's exactly the output you're looking for, where
Array[x][y] will reference an object with points at x, y.
var Coords = function(x, y) {
return {
"x" : x,
"y" : y
};
};
var Main = [];
for (var i = 0, l = 10; i < l; i++) {
Main[i] = [];
for (var j = 0, l2 = 10; j < l2; j++) {
Main[i][j] = Coords(i, j);
}
}
http://jsfiddle.net/robert/d9Tgb/
You can make a 2d array like so:
var new_array = [];
var arr_length = 10;
for(var i = 0; i < arr_length; ++i){
new_array[i] = [];
}
This post is a bit old, but here is another way to create a 2D array
var arr1=[];
var x=['a','b','c','d'];
var y=[1,2,3,4];
for( var i in x){
arr1.push([x[i],y[i]]); //For x and y of the same length
}
In JavaScript x and y can be objects arrays
jsFiddle It :)
make an empty array and push the child arrays onto it
var array = [];
array.push([1,2,3,4]);
//array[0][0] == 1
or all in one shot
var array = [[1,2,3,4], [1,2,3,4], [1,2,3,4]];

Categories

Resources