AS3 manipulation of multidimensional array - arrays

good day :)
Why is it that when i edit the hold:Array, the array:Array also gets editted?
To give an example:
function func(2, 2) { //x, y COORDINATE
var hold = array[2]; //GET COLUMN OF ARRAY
hold[2] = 2; //SET hold[x] to 2
trace(array[2][2]) //SAME AS hold[x] *but i didn't change array[x]'s value!*
}
STEP BY STEP analysis
array[] looks like this (for example):
1,1,1,1
1,1,1,1
1,1,1,1
1,1,1,1
Thus, var hold = array[y]: (where y=2)
1,1,1,1
and hold[x] = 2 (where x=2)
1,2,1,1
Now, tracing array[y][x] (where y=2, x=2)
1,2,1,1
But array[2][2] should be 1,1,1,1, because we didn't edit it's value!
Question
Why does array[] get edited when i only edited hold[]

This is because arrays (typeof will give Object) are passed by reference. To copy its values you need to clone an array in ActionScript.
Here's an explanation of this for ActionScript 2.0 (which also applies to ActionScript 3.0 but I couldn't find the version of this article for the latter).

Yes, arrays are stored against variables as a reference. This means that when you create your array array and then store it in hold to create a 2D array, you're simply storing a reference to array within hold.
For example, you would expect that if you stored a Sprite within an array and then edited that Sprite's values, that you would see those changes from anywhere else you've referenced the Sprite. This is the same for arrays.
var array:Array = [];
var another:Array = [];
var sprite:Sprite = new Sprite();
array.push(sprite);
another.push(sprite);
array[0].x = 10;
trace(another[0].x); // Also 10.
If you don't want this behaviour, you can use .slice() or .concat() to make a shallow clone of an array:
array.push(hold.slice()); // or
array.push(hold.concat());

Related

getting dimension of a 2d array in node js

I'm working on a discord bot in node js and i need to get the length of the 2 dimentions of a 2d array.
My array is structurated like this, that algo get expanded at the bottom when needed:
var users = [["","","","",""]];
now i need to know how to get the dimentions.
i was originaly doing like this, but it didn't work 🙃.
// for the y length
users.length
// for the x length
users[i].length
hope you can help
thanks in advance
Enrico 😊
Actually you almost are correct:
var users = [[1,2],[3,4]]
users.length // y
users[0].length // x
Just keeps in mind that index for each X demantion statred since zero , and might be different for each row.
Your array var users = [["","","","",""]]; is a 2d array where only the 0th index is occupied. In your case, users[i].length would probably throw a length not defined error of some sort at index 1 and beyond. You should used users[0].length to get the length of the 2d element
Assuming that none of the elements in the array varies its length from the first one you could just get the length of the first element with
var dimensions = [users.length, users[0].length]
// returns [1, 5]
In a more practical world, probably is better for you to get the dimensions on each of the elements on the array users and decide on whether to use the biggest or the smallest, naturally I'll chose the biggest.
var users = [["", "", ""], ["", ""], ["", "", "", ""]];
var elementsLength = users.map((user) => (user.length));
var lengthY = Math.max(...elementsLength);
var lengthX = users.length;
var dimensions = [lengthX, lengthY];
// returns [3, 4]
It all depends on what you want.

how to get array value by using index value of another value?

let nameArray = ["ramesh","suresh","rajesh"]
let idArray = ["100","101","102"]
Now i want value of "idArray" by using index value of "nameArray".
if nameArray index is 0. Output is 100
In Object Oriented Programming, objects should own their properties. So instead of having two data structures describe the same object, either use structs like Mr. Vadian has suggested, or have one array store all the properties of the objects:
let zippedArray = Array(zip(nameArray, idArray))
And now to get the object in a given index, you can use the following:
let index = 0
let element = zippedArray[0]
print(element.0) //ramesh
print(element.1) //100

Find all similar values in an array and group together into a new array

The problem: I have an array of objects, where the object has an x value. Each object also needs a y value, to be plotted on a Scatterplot. The y value needs to be a number between a min height(.3) and a max height(.6), and be evenly spaced based on the number of equal x values.
For example, if I have an array of objects where [(x=3)(x=4)(x=3)(x=4)(x=5)(x=3)], after iterating through the array I should have a new array of objects that looks like this: [(x=3, y=.3)(x=3, y=.45)(x=4, y=.6)(x=4, y=.3)(x=4, y=.6)(x=5, y=.45)].
The Question: What is the best way to accomplish this performance wise? Are there any packages out there that will help me iterate through the array.
Currently I've created a nested forEach loop, but the code for this is long and feels dirty to me. Any suggestions would be great :)
This is in an angular 4 project (typescript).
You definitely need the map function:
Check documantation at https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Array/map
With map you can transform you array into a new array, this way:
var array = [{"x" : 3}, {"x" : 4}, {"x": 5}, {"x" : 3}];
var counter = 1;
var newArray = array.map(object => {
var calculatedY = counter;
counter++;
//just an example, you have to calculate your y based on your conditions
return { x : object.x, y : calculatedY }
})
console.log(newArray);

Store value in an array

I am fairly new to Go. I have coded in JavaScript where I could do this:
var x = [];
x[0] = 1;
This would work fine. But in Go, I am trying to implement the same thing with Go syntax. But that doesn't help. I need to have a array with unspecified index number.
I did this:
var x []string
x[0] = "name"
How do I accomplish that?
When you type:
var x []string
You create a slice, which is similar to an array in Javascript. But unlike Javascript, a slice has a set length and capacity. In this case, you get a nil slice which has the length and capacity of 0.
A few examples of how you can do it:
x := []string{"name"} // Creates a slice with length 1
y := make([]string, 10) // Creates a slice with length 10
y[0] = "name" // Set the first index to "name". The remaining 9 will be ""
var z []string // Create an empty nil slice
z = append(z, "name") // Appends "name" to the slice, creating a new slice if required
More indepth reading about slices:
Go slices usage and internals
In JavaScript arrays are dynamic in the sense that if you set the element of an array using an index which is greater than or equal to its length (current number of elements), the array will be automatically extended to have the required size to set the element (so the index you use will become the array's new length).
Arrays and slices in Go are not that dynamic. When setting elements of an array or slice, you use an index expression to designate the element you want to set. In Go you can only use index values that are in range, which means the index value must be 0 <= index < length.
In your code:
var x []string
x[0] = "name"
The first line declares a variable named x of type []string. This is a slice, and its value will be nil (the zero value of all slice types, because you did not provide an initialization value). It will have a length of 0, so the index value 0 is out of range as it is not less that the length.
If you know the length in advance, create your array or slice with that, e.g.:
var arr [3]string // An array with length of 3
var sli = make([]string, 3) // A slice with length of 3
After the above declarations, you can refer to (read or write) values at indicies 0, 1, and 2.
You may also use a composite literal to create and initialize the array or slice in one step, e.g.
var arr = [3]string{"one", "two", "three"} // Array
var sli = []string{"one", "two", "three"} // Slice
You can also use the builtin append() function to add a new element to the end of a slice. The append() function allocates a new, bigger array/slice under the hood if needed. You also need to assign the return value of append():
var x []string
x = append(x, "name")
If you want dynamic "arrays" similar to arrays of JavaScript, the map is a similar construct:
var x = map[int]string{}
x[0] = "name"
(But a map also needs initialization, in the above example I used a composite literal, but we could have also written var x = make(map[int]string).)
You may assign values to keys without having to declare the intent in prior. But know that maps are not slices or arrays, maps typically not hold values for contiguous ranges of index keys (but may do so), and maps do not maintain key or insertion order. See Why can't Go iterate maps in insertion order? for details.
Must read blog post about arrays and slices: Go Slices: usage and internals
Recommended questions / answers for a better understanding:
Why have arrays in Go?
How do I initialize an array without using a for loop in Go?
How do I find the size of the array in go
Keyed items in golang array initialization
Are golang slices pass by value?
Can you please use var x [length]string; (where length is size of the array you want) instead of var x []string; ?
In Go defining a variable like var x=[]int creates a slice of type integer. Slices are dynamic and when you want to add an integer to the slice, you have to append it like x = append(x, 1) (or x = append(x, 2, 3, 4) for multiple).
As srxf mentioned, have you done the Go tour? There is a page about slices.
I found out that the way to do it is through a dynamic array. Like this
type mytype struct {
a string
}
func main() {
a := []mytype{mytype{"name1"}}
a = append(a, mytype{"name 2"})
fmt.Println(a);
}
golang playground link: https://play.golang.org/p/owPHdQ6Y6e

IndexOf() not working

In ActionScript 3, it seems like indexOf is not working when I try to find something like [int, int].
For example:
var array:Array = new Array();
array.push([5, 6]);
trace(array.indexOf([5, 6])); //-1
I wonder if I'm missing something here.
Arrays, like all non-primitive types in AS3, are checked by reference, not by value. Whenever you create a new instance of an object (like an array), the variable is actually a pointer to a location in memory where the object resides.
For this reason, your code won't work because you're comparing pointers to two different arrays. The language doesn't know (or care) about the contents of the objects, all it's looking to compare are the memory locations (ie the reference) to the two objects.
If we look at your code:
var array:Array = new Array();/
array.push([5, 6]);
trace(array.indexOf([5, 6])); //-1
You are actually declaring three different arrays, each with its own location in memory. Firs you create the array var, onto this you push a new array, and in this you then try to search for a new array (in indexOf([5, 6]) you are declaring a new array in-line). For this reason the search returns false, because the references do not match - even if the contents of the arrays do.
var array:Array = new Array();
var subArray:Array = [5, 6];
array.push(subArray);
trace(array.indexOf(subArray)); // 0
...this works because the reference to the array matches.
Primitive types - Numeric, Boolean, String, are compared by value eg
var a:int = 10; var b:int = 10; trace(a == b);//True
where reference types are not:
var a:Array = [5]; var b:Array = [5]; trace(a == b);//False
It would be time-consuming for the player to compare all properties of two different objects before declaring them 'equal' or not (as most complex data types do not have a distinct 'value' in the same way that a number does), so for anything non-primitive, lookups and comparisons are done by reference.
Hope this helps.
Everytime you write [5, 6] you are creating a new instance of [int, int]. When doing indexOf() and comparing objects, it only checks if that particular instance exists (by checking for a reference to the object) in the array, not another instance with the same values. You could change your code as follows for it it work as expected:
var arr0:Array = [5, 6];
var array:Array = new Array();
array.push(arr0);
trace(array.indexOf(arr0)); //should print 0 now instead of -1

Resources