Array within array - javascript

I want to make an array within an array.
It would contain some enemies with all different positions. I tried writing it like this:
var enemies = [
position = {
x: 0,
y: 0
}
];
enemies.length = 6;
This seem to work, however, I don’t know what to write when I want to call it. enemies[1].position.x doesn’t work at all. Any leads?

You probably want an array of enemy objects instead. Something like:
var enemies = [
{ position: { x: 0, y: 0 } },
{ position: { x: 0, y: 0 } },
{ position: { x: 0, y: 0 } }
];
var firstEnemy = enemies[0];
firstEnemy.position.x; // 0
var totalEnemies = enemies.length; // 3

What you want to do is
var enemies = [
{
position: { x: 0, y: 0 }
}
];
enemies[0].position.x;
Arrays index starts from 0
Also, let's deconstruct why your code doesn't throw an error, and what it exactly does.
You are declaring an array named enemies, and when declaring it you are defining a global variable named position (and its value is returned)
After execution, enemies look like this [ {x: 0, y: 0} ]

Related

Attempting to set single value at Javascript array index. It is mass-assigning values instead

I am working on a matrix algorithm but have run into a problem early on.
I have the following array:
[ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ]
I want to transform it into this:
[ [ 0, 0, 0 ], [ 0, 9, 0 ], [ 0, 0, 0 ] ]
I am attempting to set the middle value like this:
array[1][1] = 9
In an isolated context this works fine. However, in the context of my recursive loop it is not working, and I wind up with this instead:
[ [ 0, 9, 0 ], [ 0, 9, 0 ], [ 0, 9, 0 ] ]
So my question is where have I gone wrong in my program?
function matrix(n, array = initArrays(n), i = 0, j = 0) {
if (i > 0) {
return array // <--- returns: [ [ 0, 9, 0 ], [ 0, 9, 0 ], [ 0, 9, 0 ] ]
}
array = addDigit(n, array, i, j)
return matrix(n, array, i + 1, j)
}
function initArrays(n) {
const array = []
const subArray = []
for (let i = 0; i < n; i++) {
subArray.push(0)
}
for (let i = 0; i < n; i++) {
array.push(subArray)
}
return array
}
function addDigit(n, array, i, j) {
// array = [ [ 0, 0, 0 ], [ 0, 0, 0 ], [ 0, 0, 0 ] ] // <--- uncommenting this line fixes the problem. Why?
array[1][1] = 9
return array
}
matrix(3)
This is a simplified, contrived version of my program. It presently only recurs a single time, and sets the middle value of a 3x3 grid (ignore j, it is intended for future functionality).
It can be seen in action here:
Non-working: What I want to fix
https://repl.it/repls/AttentiveWideOrder
Working: Hack solution
https://repl.it/repls/CuteSoggyArchitects
The way the hack solution works is to manually reset the array immediately before attempting to assign my middle value. I have no idea why this makes any difference and would appreciate anyone who can point out my fault.
Thanks.
You need to push independent arrays to the outer array. Javascript uses an object reference and you push the same reference to the outer array.
function initArrays(n) {
const array = []
const subArray = []
for (let i = 0; i < n; i++) {
subArray.push(0)
}
for (let i = 0; i < n; i++) {
array.push(subArray.slice()); // get copy of primitive values
}
return array
}
var array = initArrays(3);
array[1][1]= 9;
console.log(array);

initializing in loop array with objects

I want to create such array in loop
dataset: [
{
x: 0,
y: 0,
},
{
x: 1,
y: 0.993,
}
]
But this way is not correct.
var array = new Array(10);
for (var i = 0; i < 5; ++i) {
array[i].x = 1;
array[i].y = 2;
}
How I can initialize in correct way?
The comments made by SLaks and squint are correct, so this answer is more of an explanation of why your code isn't working like you think it should, and an example of what you could do instead.
You created an array with room to hold 10 things but you didn't specify what those things were and so nothing is contained in the array.
var array = new Array(10);
you can visualize your array like this:
array = [undefined, undefined, undefined, undefined,...
The array you created was just a container for 10 things not yet defined. When you tried to assign the 'x' and 'y' properties of the array elements, you were were trying to operate on something that did not exist. To get what you want, I suggest creating an object that has the properties you want, with initial values, and then use your loop to add the number of elements you want.
var array = [];
var arrayObject = {x:0,y:0};
for(i=0; i < 10; i++){
array.push(arrayObject);
}
You can do this job in one assignment line as follows;
var dataSet = (new Array(10)).fill("initial y value").reduce((p,c,i) => p.concat({x:i,y:c}),[]);
console.log(dataSet);
I just couldn't figure what y values you would like to have so inserted the initial values of the array. Change them the way you like later. I hope it helps.
Replace the new Array(10) with
var array = Array.apply( {}, { length: 10 } ).map( function() { return {} });
new Array(10) is creating an array like
[ undefined, undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined]
So you are trying to assign x on undefined
If you tried
new Array(10).map(function(){ return {}; }) it will not work either.
An es6 way to do it would be
Array.from(new Array(10), () => { return { x: 1, y: 2 }; })
In JavaScript the Array acts different than in static-typed languages, so there's no need to initialize it with fixed length.
For ECMAScript 6 specification and later:
var points = [].fill.call({ length: 5 }, {x: 1, y: 1});
It produces
[{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1},
{x: 1, y: 1}]
To ensure old browsers' support use for loop:
var points = [{x: 1, y: 1}];
for (var i = 0; i < 5; i++) points.push(points[0]);

conditional in for loop misbehaving [duplicate]

This question already has answers here:
What is the most efficient way to deep clone an object in JavaScript?
(67 answers)
Closed 7 years ago.
I think its supposed to be simple, but somehow, I don't get what I'm doing wrong.
I have this code:
var currentPosition = {
x:10000,
y:10000
};
var directions = "v>v<";
var housesVisited = [{x:10000, y:10000}];
function createHouseCoordinates(data){
for(var x = 0; x<4; x++){
if(data[x]=="^"){
currentPosition.x += 1;
} else if(data[x]=="v"){
currentPosition.x -= 1;
} else if(data[x]==">"){
currentPosition.y += 1;
} else if(data[x]=="<"){
currentPosition.y -= 1;
}
housesVisited.push(currentPosition);
}
}
createHouseCoordinates(directions);
console.log(housesVisited);
It is supposed to take directions in the form of symbols, modify the current location, and create an array of objects that lists all locations that were visited. The result of the above, when I run it, gives me this (basically the end position):
[ { x: 10000, y: 10000 },
{ x: 9998, y: 10000 },
{ x: 9998, y: 10000 },
{ x: 9998, y: 10000 },
{ x: 9998, y: 10000 } ]
I was expecting:
[ { x: 10000, y: 10000 },
{ x: 9999, y: 10000 },
{ x: 9999, y: 10001 },
{ x: 9998, y: 10001 },
{ x: 9998, y: 10000 } ]
What am I doing wrong? What should I read up on to understand this better..?
Thanks in advance!
currentPosition is an object. When you're making changes to it (eg currentPosition.x += 1), you're always changing that same object.
You then push it into an array, but what you're actually pushing is a reference to that object, so all the elements of the array are pointing at the same underlying object.
To fix your code, you need to clone the object information into a new object as you push it into the array:
housesVisited.push({x: currentPosition.x, y: currentPosition.y});

Javascript array with objects

I want to create/instantiate an array objectArray with several objects, whereby the objects shall contain x and y (empty at the beginning).
The length (amount of objects) of objectArray needs to be the same as the length of i.e. arrayLong. How I have to implement that?
Finally, it should look like that (etc. corresponding to the length of arrayLong):
var objectArray = [ { x: 0, y: 0 }, { x: 0, y: 0 }, { x: 0, y: 0 } etc. ];
Simple:
var objectArray = []; // Declare the array variable
for(var i = 0; i < arrayLong; i++){ // Do something `arrayLong` times
objectArray.push({x: 0, y:0}); // Add a object to the array.
}
This assumes arrayLong is a numeric value, of course.
Another way you could do it, is this:
var objectArray = Array.apply(null, Array(arrayLong))
.map(function(){return {x: 0, y:0}});

Obtain value from JSON variable inside javascript

How to obtain value from JSON element being created dynamically. Example below. I was wondering if there is way to get the value from previous element 'top' using some javascript. (Please update the title if its incorrect or misleading)
Following this example on jsfiddle
var info = [
{
src: "http://dummyimage.com/55x80/0d0.png/fff",
pos: {
top: 93,
left: 70
},
rotate: -10,
zIndex: 3
},
{
src: "http://dummyimage.com/55x80/d00.png/fff",
pos: {
top: previousElement(top) + some dynamic value added at run time,
left: 70
},
rotate: 0,
zIndex: 2
},
]
I wouldn't do this, you can calculate it as you go based on the index.
But... if you insist:
Assuming your array is a JS literal (and not JSON, which is different) you can use a simple counter.
Using the fact assignment returns the assigned value (this is kind of ugly though):
var top = 93;
var info = [
{
src: "http://dummyimage.com/55x80/0d0.png/fff",
pos: {
top: top,
left: 70
},
rotate: -10,
zIndex: 3
},
{
src: "http://dummyimage.com/55x80/d00.png/fff",
pos: {
top: top = top + (some dynamic value added at run time),
left: 70
},
rotate: 0,
zIndex: 2
} //... keep doing top = top + sometDynamicValue on all elements
]
A more isolated example might be:
var c = 0,
arr = [
{a:c = c + 5},
{a:c = c + 5},
{a:c = c + 5},
{a:c = c + 5},
{a:c = c + 5},
]
Which creates an array of objects with an increasing by 5 a property.
I was wondering if there is way to get the value from previous element 'top' using some javascript
info is an array so all you need to do is index into it then access the prop object i.e.
var prevTop = info[someIndex].pos.top;
There's no simple syntax to get the value from the previous element in an array literal in Javascript. You have to reference it by index, like this:
pos: {
top: info[0].pos.top + value
left: 70
},
Try this function:
function DoOffset(data, offset)
{
for (var i = 1; i < data.length; i++)
{
data[i].pos.top = data[i - 1].pos.top + offset;
}
}
You can loop through the info array to change the value:
for(var i = 1, len = info.length; i < len; i++) {
info[i].pos.top = info[i - 1].pos.top + newValue;
}

Categories

Resources